网站开发环境配置难网站建设需要哪些岗位
网站开发环境配置难,网站建设需要哪些岗位,建设工程规范发布网站,html5 jq做电脑网站一、背景在高并发系统中#xff0c;如果对 Redis 进行大量写操作#xff0c;网络 RTT会成为主要性能瓶颈。举个一个简单场景#xff1a;用户给作品打标签#xff0c;需要给 Redis 的 Tag 热度排行榜#xff08;ZSet#xff09; 进行计数。如果每次操作都单独请求 Redis }执行流程Java - Redis (incrby tag1) Java - Redis (incrby tag2) Java - Redis (incrby tag3) Java - Redis (incrby tag4) ...每次操作都会产生请求 - Redis 响应 - Redis可见系统响应瓶颈就在网络往返时间。如果这时候我们使用Pipeline执行流程变成Java - Redis (cmd1 cmd2 cmd3 cmd4 ...) Redis - Java (result1 result2 result3 ...)网络往返次数从N 次变为了1 次大幅提高吞吐量。二、Redis Pipeline 原理Redis Pipeline 的核心思想是客户端一次性发送多条命令不等待响应Redis 执行完后再统一返回结果。三、Pipeline 写法1、示例我们可以这样子开启管道操作然后按需写redis命令进行批量操作stringRedisTemplate.executePipelined((RedisCallbackObject) connection - { // redis命令 return null; });这里结合我之前给的例子给出他的实战代码ListGalleryArtworkTag tagList galleryArtworkDTO.getTagIds().stream() .map(id - GalleryArtworkTag.builder() .artworkId(galleryArtworkId) .tagId(id) .build()) .collect(Collectors.toList()); if (!tagList.isEmpty()) { // Redis 批量热度更新 (一次网络请求) stringRedisTemplate.executePipelined((RedisCallbackObject) connection - { // 两种等价在 stringRedisTemplate.getStringSerializer() 底层也是用 UTF-8 // byte[] keyBytes RedisConstant.GALLERY_TAG_HOT_KEY.getBytes(StandardCharsets.UTF_8); // 先拿序列化器 RedisSerializerString serializer stringRedisTemplate.getStringSerializer(); // 获取 key byte[] keyBytes Objects.requireNonNull(serializer.serialize(RedisConstant.GALLERY_TAG_HOT_KEY)); tagList.forEach(tag - { final byte[] memberBytes String.valueOf(tag.getTagId()).getBytes(StandardCharsets.UTF_8); connection.zSetCommands().zIncrBy(keyBytes, 1.0, memberBytes); }); return null; }); }2、RedisCommandsProvider 结构我们可以看源码这里提供了很多种意味着Pipeline 内可以操作所有 Redis 数据结构connection.stringCommands() connection.hashCommands() connection.listCommands() connection.setCommands() connection.zSetCommands()3、各数据结构 Pipeline 写法String 批量写入普通写法for (User user : users) { stringRedisTemplate.opsForValue().set(user: user.getId(), user.getName()); }Pipeline 写法stringRedisTemplate.executePipelined((RedisCallbackObject) connection - { users.forEach(user - { byte[] key (user: user.getId()).getBytes(); byte[] value user.getName().getBytes(); connection.stringCommands().set(key, value); }); return null; });当然还有一些其他常用的方法Hash 批量写入普通写法hashOps.put(user:1, name, Tom); hashOps.put(user:1, age, 18);Pipeline 写法stringRedisTemplate.executePipelined((RedisCallbackObject) connection - { byte[] key user:1.getBytes(); connection.hashCommands().hSet(key, name.getBytes(), Tom.getBytes()); connection.hashCommands().hSet(key, age.getBytes(), 18.getBytes()); return null; });List 批量写入普通写法listOps.rightPush(msg:list, msg);Pipeline 写法stringRedisTemplate.executePipelined((RedisCallbackObject) connection - { messages.forEach(msg - { connection.listCommands().rPush( msg:list.getBytes(), msg.getBytes() ); }); return null; });Set 批量写入普通写法setOps.add(online:user, userId);Pipeline 写法stringRedisTemplate.executePipelined((RedisCallbackObject) connection - { users.forEach(userId - { connection.setCommands().sAdd( online:user.getBytes(), userId.getBytes() ); }); return null; });ZSet 批量写入排行榜普通写法zSetOps.incrementScore(rank, userId, 1);Pipeline 写法stringRedisTemplate.executePipelined((RedisCallbackObject) connection - { users.forEach(userId - { connection.zSetCommands().zIncrBy( rank.getBytes(), 1, userId.getBytes() ); }); return null; });原生写法写入四、注意Pipeline 不保证事务他不是事务只是批量发送数据如果要保证需要MULTI、EXEC不适合超大批量如果大批量比如10w客户端内存堆积、Redis阻塞建议是100 ~ 1000 一批