Redis命令性能优化及事务使用过程
mhr18 2024-11-13 11:13 25 浏览 0 评论
场景
假设有这样一个使用场景,依次执行下面的5条命令
命令1:hset mall:sale:freq:ctrl:860000000000001 599055114591 1(hash结构,field表示购买的商品ID,value表示购买次数)
简单说明:mall:sale:freq:ctrl:860000000000001是一个hash表;599055114591表示key;1表示key对应的value
命令2:hset mall:sale:freq:ctrl:860000000000001 599055114592 2
命令3:expire mall:sale:freq:ctrl:860000000000001 3127(设置过期时间)
简单说明:给hash表mall:mall:sale:freq:ctrl:860000000000001设置过期时间
命令4:set mall:total:freq:ctrl:860000000000001 3
简单说明:set key vlaue
命令5:expire mall:total:freq:ctrl:860000000000001 3127(设置过期时间)
简单说明: set key 过期时间
优化缘由
执行一条命令 经历的过程
- 发送命令网络传输时间
- 命令在Redis服务端队列中等待的时间
- 命令执行的时间(Redis中的slowlog只是检测这一步骤的时间)
- 结果返回的Redis客户端的时间
执行一条命令 就需要经过上面的过程,发送命令-〉命令排队-〉命令执行-〉返回结果
那么执行5条命令,可想而知,性能优化的空间还是蛮大的,
下面咱们来进行优化一下吧
优化
第一次优化:利用hmset命令将两条hmset命令合二为一
命令1和命令2 合二为一
hmset mall:sale:freq:ctrl:860000000000001 599055114591 1 599055114592 2
expire mall:sale:freq:ctrl:860000000000001 3127
set mall:total:freq:ctrl:860000000000001 3
expire mall:total:freq:ctrl:860000000000001 3127
第二次优化:将set和expire命令合二为一
将命令4和命令5合二为一
命令a:hmset mall:sale:freq:ctrl:860000000000001 599055114591 1 599055114592 2
命令b: expire mall:sale:freq:ctrl:860000000000001 3127
命令c: setex mall:total:freq:ctrl:860000000000001 3127 3
第三次优化:使用pipeline
需要注意:RedisCluster中使用pipeline时必须满足pipeline打包的所有命令key在RedisCluster的同一个slot上
分析下是否在同一个slot上
slot原理简介
Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
集群中的每个节点负责处理一部分哈希槽。
举个例子, 一个集群可以有三个哈希槽, 其中:
节点 A 负责处理 0 号至 5500 号哈希槽。
节点 B 负责处理 5501 号至 11000 号哈希槽。
节点 C 负责处理 11001 号至 16384 号哈希槽。
这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。 比如说:
如果用户将新节点 D 添加到集群中, 那么集群只需要将节点 A 、B 、 C 中的某些槽移动到节点 D 就可以了。
与此类似, 如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(不包含任何哈希槽)的节点 A 就可以了。
因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞, 所以无论是添加新节点还是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 都不会造成集群下线。
结论
由此可知 命令a和命令b在同一个slot上,命令c在另外一个slot上
所以命令a和命令b用pipline来处理
如何使用pipline
- 先创建一个txt文件
vim pipeline.txt
hmset mall:sale:freq:ctrl:860000000000001 599055114591 1 599055114592 2
expire mall:sale:freq:ctrl:860000000000001 3127
- 格式化 使得 这个文本文件中每一行都必须以\r\n而不是\n结束
需要安装下dos2unix
a、brew install dos2unix
b、unix2dos pipeline.txt
- 命令执行
cat pipeline.txt | redis-cli --pipe
第四次优化 使用 高级特性:hashtag
由 CRC16(key) % 16384 来计算键 key 属于哪个槽 可知,key决定了存储在哪个slot上,那么使用hashtag可以使得 满足部分key一致的所有key都存储在同一个slot上
比如
mall:sale:freq:ctrl:{860000000000001} 只要key中有{860000000000001}这一部分,就一定落在同一个slot上
**注意:使用hashtag特性 不能把key的离散性变得非常差 **
- 离散性好
mall:sale:freq:ctrl:{860000000000001} 这种key还是与用户相关
- 离散性差
mall:{sale:freq:ctrl}:860000000000001
所有的key都会落在同一个slot上,导致整个Redis集群出现严重的倾斜问题
经过这4次优化 perfect ==> 5条Redis命令压缩到3条Redis命令,并且3条Redis命令只需要发送一次,并且结果也一次就能全部返回
pipline
- 未使用pipline
- 使用了pipline
- 性能对比
这是一组统计数据出来的数据,使用Pipeline执行速度比逐条执行要快,特别是客户端与服务端的网络延迟越大,性能体能越明显
性能测试代码
pipeline 实现 mdel
redis提供了mset、mget方法 但没有提供mdel方法 可以借助pipeline实现
将不同类型的操作命令合并提交
原生批命令(mset, mget)与Pipeline对比
- 原生批命令是原子性,pipeline是非原子性(原子性概念:一个事务是一个不可分割的最小工作单位,要么都成功要么都失败。原子操作是指你的一个业务逻辑必须是不可拆分的. 处理一件事情要么都成功,要么都失败,原子不可拆分)
- 原生批命令一命令多个key, 但pipeline支持多命令(存在事务),非原子性
- 原生批命令是服务端实现,而pipeline需要服务端与客户端共同完成
使用pipeline组装的命令个数不能太多,不然数据量过大,增加客户端的等待时间,还可能造成网络阻塞,可以将大量命令的拆分多个小的pipeline命令完成
事务
- redsi事务
- discard事务
- 命令错误,语法不正确,导致事务不能正常结束
- 运行错误,语法正确,但类型错误,事务可以正常结束
- watch命令
使用watch后, multi失效,事务失效
WATCH的机制是:
在事务EXEC命令执行时,Redis会检查被WATCH的key,
只有被WATCH的key从WATCH起始时至今没有发生过变更,EXEC才会被执行。
如果WATCH的key在WATCH命令到EXEC命令之间发生过变化,则EXEC命令会返回失败。
源码地址
https://gitee.com/pingfanrenbiji/springboot-jedisCluster/blob/master/demo/src/main/java/com/example/pipline/PipelineTest.java
参考文档
https://www.jianshu.com/p/8849c0b5753d
http://www.gxlcms.com/redis-377198.html
https://blog.csdn.net/huangbaokang/article/details/88028814
https://blog.csdn.net/w1lgy/article/details/84455579
官方文档 :
http://redisdoc.com/topic/cluster-tutorial.html?highlight=slot
相关推荐
- 说说Redis的单线程架构(redis的单线程模型)
-
一句话总结Redis采用单线程处理命令请求,避免了多线程的上下文切换和锁竞争,保证原子性操作。其基于内存的高效执行和I/O多路复用模型支撑了高并发性能。网络I/O和持久化操作(如RDB/AOF)由后台...
- 答记者问之 - Redis 的高效架构与应用模式解析
-
问:极客程序员你好,请帮我讲一讲redis答:redis主要涉及以下核心,我来一一揭幕Redis的高效架构与应用模式解析Redis是一个开源的内存数据存储系统,因其高性能、丰富的数据结构和易用性...
- Redis的5种核心数据结构,及其最经典的“应用场景”
-
Redis凭什么稳坐缓存界头把交椅?全靠这五个“身怀绝技”的数据结构!在分布式系统的江湖里,Redis就像一位身怀绝技的武林高手,而它的五大核心数据结构正是克敌制胜的五套绝学。今天咱们就来拆解这些独门...
- 精准定位文件包含漏洞:代码审计中的实战思维
-
前言最近看到由有分析梦想cms的,然后也去搭建了一个环境看了一看,发现了一个文件包含漏洞的点,很有意思,下面是详细的复现和分析,以后代码审计又多了一中挖掘文件包含漏洞的新思路环境搭建下载https...
- ARDM:一款国产跨平台的Redis管理工具
-
ARDM(AnotherRedisDesktopManager)是一款免费开源的Redis桌面管理客户端,支持Windows、Mac、Linux跨平台。功能特性ARDM提供的主要功能如...
- SpringBoot的Web应用开发——Web缓存利器Redis的应用!
-
Web缓存利器Redis的应用Redis是目前使用非常广泛的开源的内存数据库,是一个高性能的keyvalue数据库,它支持多种数据结构,常用做缓存、消息代理和配置中心。本节将简单介绍Redis的使...
- Windows服务器部署CRMEB开源电商系统,详细教程来了!
-
安装PHP已经安装过PHP的可以跳过首先安装VC运行库下载地址https://docs.microsoft.com/zh-cn/cpp/windows/latest-supported-vc-redi...
- Windows系统下Redis各个安装包介绍与选择指南
-
简介Redis作为高性能的键值数据库,广泛应用于缓存、消息队列等场景。在Windows系统中部署Redis时,用户可以选择多种安装包以满足不同的需求。本文将详细介绍以下Redis8.0.3版本的安装...
- 从面试题入手,深度剖析Redis Cluster原理
-
揭开RedisCluster的神秘面纱**在当今数字化浪潮中,数据量呈爆炸式增长,应用程序对数据存储和处理的要求也日益严苛。Redis作为一款高性能的内存数据库,凭借其出色的读写速度和丰富的数...
- 给大家推荐些好的c语言代码的网站
-
C语言,那就来推荐几个吧,部分含有C++:1、TheLinuxKernelArchives(kernel.org)Linux内核源码,仅限于C,但内核庞大,不太适合新手;2、redis(redi...
- Redis String 类型的底层实现与性能优化
-
RedisString是Redis中最基础也是应用最广泛的数据类型,它能存储文本、数字、二进制数据等多种形式的信息。深入理解其底层实现对构建高性能分布式系统至关重要。Redis字符串的底层结...
- 阿里面试问:Redis 为什么把简单的字符串设计成 SDS?
-
分享了一道面阿里的redis题,我看了以后觉得挺有意思。题目大致是这样的面试官:了解redis的String数据结构底层实现嘛?铁子:当然知道,是基于SDS实现的面试官:redis是用C语言开发的,那...
- 编程语言那么多,为何C语言能成为最成功的语言?
-
编程语言那么多,为何C语言能成为最成功的语言?2025年嵌入式岗位暴增47%,新人却还在问"C语言过时了吗"。真相是连机器人关节驱动都得靠它写,不会指针连芯片手册都看不懂。见过用Pyt...
- go-zero 使用 redis 作为 cache 的 2 种姿势
-
在go-zero框架内,如在rpc的应用service中,其内部已经预置了redis的应用,所以我们只需要在配置中加入相关字段即可,另外,在svcContext声明redisc...
- Redis事务深度解析:ACID特性、执行机制与生产实践指南
-
一、Redis事务的本质与核心机制Redis事务通过MULTI、EXEC、WATCH等命令实现,其本质是将多个命令序列化后一次性执行,而非传统数据库的严格事务模型。核心特点如下:命令队列化:MULT...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle主从同步 (56)
- oracle 乐观锁 (53)
- redis 命令 (83)
- php redis (97)
- redis 存储 (67)
- redis 锁 (74)
- 启动 redis (73)
- redis 时间 (60)
- redis 删除 (69)
- redis内存 (64)
- redis并发 (53)
- redis 主从 (71)
- redis同步 (53)
- redis 哨兵 (52)
- redis结构 (53)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)