引入一个大家都用的到的需求来说吧。

需求:要在三主三从的redis集群,存入数据,会对数据进行批量删除操作,数据要求要在redis集群负载均衡。

思路:

1.存入数据好办

1 var connect = ConnectionMultiplexer.Connect(redisConn);
2 var redisDb = connect.GetDatabase();
3 var res1 = redisDb.StringSet("1", DateTime.Now.ToString(), TimeSpan.FromSeconds(600));
4 var res2 = redisDb.StringSet("1111", DateTime.Now.ToString(), TimeSpan.FromSeconds(600));

2.批量删除直接异常

1 redisDb.KeyDelete(new RedisKey[] { "1", "1111" });

Ex:"Multi-key operations must involve a single slot; keys can use 'hash tags' to help this, i.e. '{/users/12345}/account' and '{/users/12345}/contacts' will always be in the same slot"

3.查到异常是因为redis hash slot 机制导致的,什么是 hash slot?
hash slot 介绍:https://redis.io/topics/cluster-tutorial

4.加上hash slot 字符串,让key进入同一个slot
var res1 = redisDb.StringSet("{myslot}key1", DateTime.Now.ToString(), TimeSpan.FromSeconds(600));
var res2 = redisDb.StringSet("{myslot}key2", DateTime.Now.ToString(), TimeSpan.FromSeconds(600));
redisDb.KeyDelete(new RedisKey[] { "{myslot}key1", "{myslot}key2" });
能进行批量操作,但是都被分配到了同一台服务器上的同一个槽点,不负载均衡。

5.如何负载均衡, 让Key分布到各个服务器,并且可以批量操作?
如果知道每个槽点对应的字符串,key可以按照算法计算出自己对应的字符串,加上后,就可以进行分组批量增删改操作。

6.hash slot 计算方法
HASH_SLOT = CRC16(key) mod 16384 (crc16-XMODEM)
介绍 :https://redis.io/topics/cluster-spec

7.net core 计算出16384个slot 字符串 算法例子和 结果模板

 1         static void Main(string[] args)
2 {
3 var data = new Dictionary<int, string>();
4 var i = 0;
5 while (data.Keys.Count < 16384)
6 {
7 var temp = i.ToString("X");
8 var value = Crc16(Encoding.UTF8.GetBytes(temp)) % 16384;
9 data[int.Parse(value.ToString())] = temp;
10 i++;
11
12 }
13 var sb = new StringBuilder();
14 foreach (var item in data.OrderBy(s => s.Key))
15 {
16 var temp = $"slot num:{item.Key} str:{item.Value} \r\n";
17 Console.WriteLine(temp);
18 sb.Append(temp);
19 }
20 File.WriteAllText("data.txt", sb.ToString());
21 Console.ReadLine();
22 }
23 private static ushort Crc16(byte[] bytes)
24 {
25 ushort poly = 0x1021;
26 ushort[] table = new ushort[256];
27 ushort initialValue = 0x0;
28 ushort temp, a;
29 ushort crc = initialValue;
30 for (int i = 0; i < table.Length; ++i)
31 {
32 temp = 0;
33 a = (ushort)(i << 8);
34 for (int j = 0; j < 8; ++j)
35 {
36 if (((temp ^ a) & 0x8000) != 0)
37 temp = (ushort)((temp << 1) ^ poly);
38 else
39 temp <<= 1;
40 a <<= 1;
41 }
42 table[i] = temp;
43 }
44 for (int i = 0; i < bytes.Length; ++i)
45 {
46 crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]);
47 }
48 return crc;
49 }

  data.txt 文件下载

8.校验算出来的字符串 对应 的slot位置 是否正确

9.批量设置和批量删除方法
假定三主三从,那么三台服务器,取九个slot字符串,这九个是均分的位置(均分利于集群扩展)。即16384/10=1638 1638是第一位,1638*2是第二位,以此类推取字符串
共九个["1A73F","18B13","1AAD3","184FF","143BF","18413","17B8D","18BFF","1B1C4"]
先分组,再批量插入,再批量删除

 1 try
2 {
3 var redisConn = "{集群地址}";
4 var connect = ConnectionMultiplexer.Connect(redisConn);
5 var redisDb = connect.GetDatabase();
6 var res1 = redisDb.StringSet("1", DateTime.Now.ToString(), TimeSpan.FromSeconds(600));
7 var res2 = redisDb.StringSet("1111", DateTime.Now.ToString(), TimeSpan.FromSeconds(600));
8 redisDb.KeyDelete(new RedisKey[] { "1", "1111" });
9
10
11 var redisSlotKeyList = new string[] { "1A73F", "18B13", "1AAD3", "184FF", "143BF", "18413", "17B8D", "18BFF", "1B1C4" };
12 var userIdArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
13 //group
14 var dic = new Dictionary<int, Dictionary<RedisKey,RedisValue>>();
15 foreach (var userId in userIdArray)
16 {
17 var index = userId % redisSlotKeyList.Length;
18 var slotKey = redisSlotKeyList[index];
19 var redisKey = $"{{{slotKey}}}test_{userId}";
20 Console.WriteLine($"{ redisKey} {userId}");
21 if (dic.ContainsKey(index))
22 {
23 dic[index].Add(redisKey, DateTime.Now.ToLongTimeString());
24 }
25 else
26 {
27 dic[index] = new Dictionary<RedisKey, RedisValue> { { new RedisKey(redisKey), new RedisValue("values") } };
28 }
29 }
30
31 //set
32 foreach (var item in dic)
33 {
34 var addRes = redisDb.StringSet(item.Value.ToArray());
35 Console.WriteLine(addRes);
36 }
37
38
39 //delete
40 foreach (var item in dic)
41 {
42 var deleteRes = redisDb.KeyDelete(item.Value.Keys.ToArray());
43 Console.WriteLine(deleteRes);
44 }
45
46
47
48 }
49 catch (Exception ex)
50 {
51 throw ex;
52 }

10.注意点
集群的分割slot配置不一定的均分的,提前先查看,命令:cluster nodes。 查看之后再根据实际情况取slot string

C# redis集群批量操作之slot计算出16384个字符串的更多相关文章

  1. Redis集群批量操作

    Redis在3.0版正式引入了集群这个特性,扩展变得非常简单.然而当你开心的升级到3.0后,却发现有些很好用的功能现在工作不了了, 比如我们今天要聊的pipeline功能等批量操作. Redis集群是 ...

  2. 深入浅出—Redis集群的相关详解

    前言: 这篇文章主要介绍了Redis集群的相关,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值. 注意!要求使用的都是redis3.0以上的版本,因为3.0以上增加了red ...

  3. redis集群报错:(error) CLUSTERDOWN Hash slot not served

    百度上坑太多,如果你遇到搭建redis集群的时候出现这个错误在百度上找到解决办法基本上都是坑. 首先集群搭建完成后,你肯定去登陆redis进行测试 1.redis01/redis-cli -h &qu ...

  4. .NET使用Task动态创建多任务多线程并行程序计算Redis集群keys计算

    Task是一个很好用的多任务处理类,并且通过Task可以对任务进行很好的控制. 下面将通过代码实现Redis集群在使用IServer.keys时通过多任务对多个服务器示例进行并行计算,并对返回key做 ...

  5. redis集群错误解决:/usr/lib/ruby/gems/1.8/gems/redis-3.0.0/lib/redis/client.rb:79:in `call': ERR Slot 15495 is already busy (Redis::CommandError)

    错误信息: /usr/lib/ruby/gems/1.8/gems/redis-3.0.0/lib/redis/client.rb:79:in `call': ERR Slot 15495 is al ...

  6. Redis集群环境各节点无法互相发现与Hash槽分配异常 CLUSTERDOWN Hash slot not served的解决方式

    总结/朱季谦 在搭建Redis5.x版本的集群环境曾出现各节点无法互相发现与Hash槽分配异常 CLUSTERDOWN Hash slot not served的情况,故而把解决方式记录下来. 在以下 ...

  7. Redis集群最佳实践

    今天我们来聊一聊Redis集群.先看看集群的特点,我对它的理解是要需要同时满足高可用性以及可扩展性,即任何时候对外的接口都要是基本可用的并具备一定的灾备能力,同时节点的数量能够根据业务量级的大小动态的 ...

  8. redis 集群配置实战

    文章转载自:http://hot66hot.iteye.com/blog/2050676 最近研究Redis-cluster,正好搭建了一个环境,遇到了很多坑,系统的总结下,等到redis3 rele ...

  9. redis集群讨论

    一.生产应用场景 二.存储架构演变 三.应用最佳实践 四.运维经验总结 第1.2节:介绍redis cluster在唯品会的生产应用场景,以及存储架构的演变.第3节:redis cluster的稳定性 ...

随机推荐

  1. elasticsearch mysql配置

    1,开启bin-log 2,binglog_foramt格式必须为row 3,配置server_id为1001 4,binlog-row-image 必须为full log-bin=mysql-bin ...

  2. 【bug录】安装项目编译环境bug录

    安装mySQL是遇到一些问题: 刚开始按照教程配置int文件,看着图标没有显示正确,把隐藏文件夹后缀名去掉, mysql由两种版本,zip和msi格式,我用的是zip格式,mysql后进行解压,记住解 ...

  3. xlrd加载Excal表格编码格式的问题

    Python自动化测试中,利用xlrd加载文件名,代码如下: newpath = os.chdir('文件所在目录') filename = "文件名.xlsx" 报IOError ...

  4. 使用微创联合M5S空气检测仪、树莓派3b+、prometheus、grafana实现空气质量持续监控告警WEB可视化

    1.简介 使用微创联合M5S空气检测仪.树莓派3b+.prometheus.grafana实现空气质量持续监控告警WEB可视化 grafana dashboard效果: 2.背景 2.1 需求: 1. ...

  5. Luogu P5087 数学

    题意 给定一个长度为 \(n\) 的序列 \(a_i\),求出在这个序列中所有选出 \(k\) 个元素方案中元素的乘积之和. \(\texttt{Data Range:}1\leq n\leq 10^ ...

  6. elk部署(实操二)

    续上篇 https://www.cnblogs.com/wangql/p/13373022.html 安装logstash  下载地址:wget https://artifacts.elastic.c ...

  7. 面经手册 · 第16篇《码农会锁,ReentrantLock之公平锁讲解和实现》

    作者:小傅哥 博客:https://bugstack.cn 专题:面经手册 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 Java学多少才能找到工作? 最近经常有小伙伴问我,以为我的经验来看 ...

  8. Typora设置Vue主题

    平时看视频,发现好多老师使用 Typora 时,界面跟我的不一样,好看一些,后来查了下才知道老师使用了Vue主题,接下来我就记录下设置Vue主题的步骤吧 一.下载Vue主题 地址:http://the ...

  9. 白话科普系列——双十一,竟然是一场有“预谋”的DDoS攻击?

    随著互联网与信息技术的发展,所有人都在享受互联网带来的舒适和便利.如今,无论是个人社交行为,还是商业活动都早已离不开互联网. 但是,网络空间在创造机遇的同时,也带来了威胁.随着企业价值.知名度的提高. ...

  10. 《Machine Learning in Action》—— 剖析支持向量机,单手狂撕线性SVM

    <Machine Learning in Action>-- 剖析支持向量机,单手狂撕线性SVM 前面在写NumPy文章的结尾处也有提到,本来是打算按照<机器学习实战 / Machi ...