本文已参与[新人创作礼]活动,一同开启创作之路。
布景:redis集群
-
履行lua脚本时
不同于单机状况,lua脚本在履行时需求确保key在同一个node节点上,换句话说也就是需求保证 slot=crc16%16384,通过对key进行hash运算,其slot会分布在同一个node节点所属规模。
处理思路:
为了使key都落在一个node节点上能够通过增加 {} hashTag来实现。
原理:
相同的hashtag被分配到相同的节点,相同的槽。
hash算法选用crc16。crc16算法为redis自己封装的,源码位置:https://github.com/redis/redis/blob/6.2.6/src/crc16.c。
-
golang选择客户端
一开始复用了项目里存在的golang客户端 即选用的 go-redis
github.com/go-redis/redis v6.15.9+incompatible
项目上线后通过granfa监控打点观测到redis的集群远超预想
从上面图形能够看出redis集群的p98响应在k级毫秒以上,其中连续是因为顺次扫除置疑的点[qps为300,属实比较低了:scream: ]
- lua脚本太杂乱导致redis履行较慢(:sweat: 吃了知识点掌握不牢固的亏,仅用 exists 进行测验发现无变化 )
- 置疑集群存在某节点故障(:japanese_goblin: 换成单节点验证发现 无变化)
- 置疑命中key的概率低的问题(:pleading_face: 换成redis中存在的key验证 无变化)
- 将问题仍是放在了redis集群上 ,还好此集群未正式运用(也是敢压测的原因[:eyes: 要对线上环境抱有敬畏之心:eyes:])
履行下述指令进行redis的压测:
redis-benchmark -h 127.0.0.1 -p 6379 -t set,get -n 10000 -q
redis-cli -h 127.0.0.1 -p 6379 --intrinsic-latency 60
从压测数据来看 latency 均匀为15.5906ms,观测还可行。而其set指令均匀不到3k,对集群仍是有所
置疑【有可能网络带宽非本地原因,此处无确认结论】,对比了另外一组redis集群发现无影响
- 集群没问题,指令也简略(大佬的协助下开始测验golang客户端的问题)
原运用的客户端
1、mod文件
github.com/go-redis/redis v6.15.9+incompatible
2、部分代码【留意6.15.9的时分SMembers 无上下文概念】
//构建客户端
ClusterPool := redis2.NewClusterClient(&redis2.ClusterOptions{
Addrs: strings.Split(addr,","),
})
//履行指令并计算耗时
fmt.Println("时刻redis cluster client begin:", time.Now())
testData := ClusterPool.SMembers("798176a1b809edaf956bb2c6ceda9280")
fmt.Println("时刻redis cluster client end:", time.Now())
fmt.Println(testData) //为了验证成功输出数据
原运用的客户端晋级下
1、mod文件
github.com/go-redis/redis/v8 v8.11.5
2、部分代码【此刻SMembers 存在上下文了】
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
//构建客户端
ClusterPool := redis2.NewClusterClient(&redis2.ClusterOptions{
Addrs: strings.Split(addr,","),
})
//履行指令并计算耗时
fmt.Println("时刻redis cluster client begin:", time.Now())
testData := ClusterPool.SMembers(ctx,"798176a1b809edaf956bb2c6ceda9280")
fmt.Println("时刻redis cluster client end:", time.Now())
fmt.Println(testData) //为了验证成功输出数据
Nice的客户端
1、mod文件
2、部分代码
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
//构建客户端
cluster, _ := (radix.ClusterConfig{}).New(ctx, strings.Split(addr,","))
//履行指令并计算耗时
fmt.Println("时刻redis cluster client begin:", time.Now())
str:=[]string{}//此处一定要预先知道存储的类型
err:= cluster.Do(ctx, radix.Cmd(&str, "smembers", "798176a1b809edaf956bb2c6ceda9280"))
fmt.Println("时刻redis cluster client end:", time.Now())
fmt.Println(testData,err) //为了验证成功输出数据
上述两图分别为 radix 与 go—redis(v6),radix 与 go-redis(v8),实验证明 v8是远强于v6的,但是与radix仍是有10倍之差
友情提示,选用客户端的时分能够按照官方推荐的包
通过上述疑问点的扫除法,最终选用radix的客户端,其耗时如下:
从上图能够看到redis集群在10k恳求的状况下,p98为1.4ms左右,符合预期。大工高成~
程序猿的快乐就是如此简略了~,高兴