当前位置: 首页 > wzjs >正文

长宁广州网站建设哔哩哔哩网页版在线观看

长宁广州网站建设,哔哩哔哩网页版在线观看,网易企业邮箱收不到邮件怎么回事,网站设计与网页配色实例精讲pdf在正常情况下,我们每次发送 Redis 命令时,客户端会等待 Redis 服务器的响应,直到接收到结果后,才会发送下一个命令。这种方式虽然保证了操作的顺序性,但在执行大量命令时会产生很大的网络延迟。 通过 Pipeline 技术&a…

在正常情况下,我们每次发送 Redis 命令时,客户端会等待 Redis 服务器的响应,直到接收到结果后,才会发送下一个命令。这种方式虽然保证了操作的顺序性,但在执行大量命令时会产生很大的网络延迟。

通过 Pipeline 技术,我们的客户端可以将多个命令同时发送给 Redis 服务器,并且不需要等待每个命令的返回结果,直到所有命令都被执行完毕,客户端再一起获取返回值。这样能减少每个命令的等待时间,大幅提高执行效率。

Redis Pipeline 是一种优化 Redis 操作的机制,通过将多个命令打包发送到 Redis 服务器,减少客户端与服务器之间的网络往返时间(RTT),从而显著提升性能。 

在默认情况下,Redis 客户端与服务器之间的通信是请求-响应模式,即:

  1. 客户端发送一个命令到服务器。

  2. 服务器执行命令并返回结果。

  3. 客户端等待响应后再发送下一个命令。

这种模式在命令数量较少时没有问题,但在需要执行大量命令时,网络往返时间(RTT)会成为性能瓶颈。所以我们需要实现下面目的:

  • 将多个命令打包发送到服务器。

  • 服务器依次执行这些命令,并将结果一次性返回给客户端。

  • 减少网络开销,提升性能。

以下是一个简单的 Java 示例,展示了如何使用 Jedis(Redis 的一个 Java 客户端)执行 Pipeline:

注意:批处理时不建议一次携带太多命令,并且Pipeline的多个命令之间不具备原子性。

// 创建 Jedis 实例
Jedis jedis = new Jedis("localhost", 6379);// 使用 pipelining 方式批量执行命令
Pipeline pipeline = jedis.pipelined();// 批量操作:使用 pipeline 来缓存命令
for (int i = 0; i < 1000; i++) {pipeline.set("key" + i, "value" + i);
}// 同步执行所有命令
pipeline.sync();
  • pipelined() 方法: 创建一个 Pipeline 对象,它缓存所有要执行的命令。
  • 批量设置命令: 通过 pipeline.set() 将多个 SET 命令放入管道中,但命令并不会立即执行。
  • sync() 方法: 通过调用 sync() 方法,客户端将会把所有缓存的命令一次性发送给 Redis,并等待它们完成执行。

但是这些都是在单机模式下的批处理,那对于集群来说该如何使用呢?

向MSet或Pipeline这样的批处理需要在一次请求中携带多条命令,而此时如何Redis是一个集群,那批处理命令的多个key必须落在同一个插槽中,否则就会导致执行失败。

 一般推荐使用并行插槽来解决,如果使用hash_tag,可能会出现大量的key分配同一插槽导致数据倾斜,而并行插槽不会。

那么这里我们模拟一下并行插槽实现:

将多个键值对按照Redis集群的槽位进行分组,然后分别使用jedisCluster.mset()方法按组设置键值对。

public class JedisClusterTest {// 声明一个JedisCluster对象,用于与Redis集群进行交互private JedisCluster jedisCluster;// 在每个测试方法执行之前,初始化JedisCluster连接@BeforeEachvoid setUp() {// 配置Jedis连接池JedisPoolConfig poolConfig = new JedisPoolConfig();poolConfig.setMaxTotal(8);poolConfig.setMaxIdle(8);poolConfig.setMinIdle(0);poolConfig.setMaxWaitMillis(1000);// 创建一个HashSet,用于存储Redis集群的节点信息HashSet<HostAndPort> nodes = new HashSet<>();// 添加Redis集群的节点信息(IP和端口)nodes.add(new HostAndPort("192.168.150.101", 7001));nodes.add(new HostAndPort("192.168.150.101", 7002));nodes.add(new HostAndPort("192.168.150.101", 7003));nodes.add(new HostAndPort("192.168.150.101", 8001));nodes.add(new HostAndPort("192.168.150.101", 8002));nodes.add(new HostAndPort("192.168.150.101", 8003));// 使用配置的连接池和节点信息初始化JedisCluster对象jedisCluster = new JedisCluster(nodes, poolConfig);}// 测试方法:使用mset命令一次性设置多个键值对@Testvoid testMSet() {// 使用JedisCluster的mset方法,一次性设置多个键值对// 但是jedisCluster默认是无法解决批处理问题的,需要我们手动解决jedisCluster.mset("name", "Jack", "age", "21", "sex", "male");}// 测试方法:使用mset命令按槽位分组设置多个键值对@Testvoid testMSet2() {// 创建一个HashMap,用于存储多个键值对Map<String, String> map = new HashMap<>(3);map.put("name", "Jack");map.put("age", "21");map.put("sex", "Male");// 将map中的键值对按照Redis集群的槽位进行分组Map<Integer, List<Map.Entry<String, String>>> result = map.entrySet().stream().collect(Collectors.groupingBy(// 使用ClusterSlotHashUtil计算每个键对应的槽位entry -> ClusterSlotHashUtil.calculateSlot(entry.getKey())));// 遍历按哈希槽分组后的结果for (List<Map.Entry<String, String>> list : result.values()) {// 创建一个数组用于批量设置Redis的键值对String[] arr = new String[list.size() * 2];  // 每个键值对包含两个元素int j = 0;  // 索引变量,用于在数组中定位位置for (int i = 0; i < list.size(); i++) {j = i << 1;  // 通过位移计算数组中的位置Map.Entry<String, String> e = list.get(i);  // 获取当前的键值对arr[j] = e.getKey();  // 将键放入数组中arr[j + 1] = e.getValue();  // 将值放入数组中}// 批量设置Redis集群中的键值对jedisCluster.mset(arr);}}// 在每个测试方法执行之后,关闭JedisCluster连接@AfterEachvoid tearDown() {// 如果JedisCluster对象不为空,则关闭连接if (jedisCluster != null) {jedisCluster.close();}}
}

而在Redis集群环境下,如果需要批量获取多个键的值,可以使用multiGet方法。multiGetRedisTemplate提供的一个方法,用于一次性获取多个键的值。然而,需要注意的是,multiGet在集群环境下要求所有键必须位于同一个槽位(slot),否则会抛出异常。

@Service
public class RedisService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 跨槽位批量获取多个键的值*/public Map<String, Object> batchGetCrossSlot(List<String> keys) {// 按槽位分组Map<Integer, List<String>> slotKeyMap = keys.stream().collect(Collectors.groupingBy(ClusterSlotHashUtil::calculateSlot));// 存储最终结果Map<String, Object> result = new HashMap<>();// 对每个槽位的键分别调用multiGetfor (Map.Entry<Integer, List<String>> entry : slotKeyMap.entrySet()) {List<String> slotKeys = entry.getValue();List<Object> slotValues = redisTemplate.opsForValue().multiGet(slotKeys);// 将结果存入Mapfor (int i = 0; i < slotKeys.size(); i++) {result.put(slotKeys.get(i), slotValues.get(i));}}return result;}/*** 测试跨槽位批量获取方法*/public void testBatchGetCrossSlot() {List<String> keys = Arrays.asList("name", "age", "sex");Map<String, Object> values = batchGetCrossSlot(keys);// 打印结果values.forEach((key, value) -> {System.out.println("Key: " + key + ", Value: " + value);});}
}

http://www.dtcms.com/wzjs/562656.html

相关文章:

  • 东莞网站建设 食品厂龙之向导官网
  • 外贸网站建设优化营销淘宝网页版登录电脑版
  • 临沂网站建设多少钱网站搭建 成都
  • 设计网站价格表一个网站怎么做pc和移动端
  • 我想自己建立一个网站同城58招聘信息
  • 中学生做网站建一个网上商城需要多少钱
  • 网站商务通js代码采购平台app
  • 重庆综合网站建设配件自己做购物网站
  • 做旅游攻略的网站好网站备案是一年一次吗
  • 做外贸仿牌网站成都网站建设-中国互联
  • 汕头网站搭建多少钱上海人才服务网
  • 产品网站更新内容百度一下首页百度
  • 建设公司网站的意义微信公众号营销
  • 计科专业毕设做网站哪个省份网站建设便宜
  • 邓亚萍20亿做网站外贸网站建站要多少钱
  • 学校信息门户网站建设关注公众号一单一结兼职
  • 好的网站具备中小企业网站建设行情
  • 网站地图怎样做响应式网站建设服务
  • 天津网站建设公司推荐h5制作步骤
  • 建筑网站设计方案什么样的笔记本电脑适合网站开发
  • 自己买服务器建设网站建筑信用信息查询平台
  • 陶瓷 网站模板wordpress 主题无法更换
  • 做查询系统网站做网站如何容易被百度抓取
  • 亚网站建设网站空间域名注册
  • 沈阳城市建设学院网站php招生网站开发
  • 静态网页模板 网站模板如何创新网站建设模式
  • 网站空间推荐东莞市公司网站建设
  • 成都网站建设司做网站页面该建多大的画布
  • 有什么网站可以做跳转连接的wordpress搜索页面怎么仿
  • 绵阳做手机网站密云富阳网站建设