【Redis】解码Redis字符串:命令执行与内存优化背后的编码逻辑
📚️前言
🌟🌟🌟精彩读导
本次我们将全面剖析Redis的核心技术要点,包括其丰富的数据类型体系、高效的编码方式以及秒级响应的性能奥秘。对于渴望深入理解Redis底层机制的技术爱好者,这是一次难得的学习机会!
🔍 推荐扩展阅读
想了解更多数据库技术干货?欢迎访问小编的CSDN技术博客: 👉 GGBondlctrl-CSDN博客 👈 (持续更新分布式系统、中间件等深度技术文章)
💖 读者互动
您的每一个👍点赞、⭐收藏和✏️评论,都是我们持续输出优质技术内容的强大动力!期待在评论区看到您的见解~
目录
📚️前言
📚️1.String类型详解
🚀1.1基本情况
🚀1.2基本命令
1.2.1SET
1.2.2GET
1.2.3MSET与MGET
1.2.4SETNX
1.2.5SETEX与PSETEX
1.2.6运算操作
1.2.7append
1.2.8getrange与setrange
1.2.9strlen
📚️2.string内部编码方式
🚀2.1内部编码
📚️3.string类型应用场景
🚀3.1web服务
🚀3.2string类型的计数功能
🚀3.3会话机制的利用
📚️4.总结
📚️1.String类型详解
🚀1.1基本情况
redis中的字符串,直接按照二进制数据方式进行存储(不会做任何编码转换,存啥取啥)
🌟在redis的value中是可以存储:文本,整数,json,xml,二进制的图片以及视频
但是在redis中的音频体积比较大,redis对于string类型的限制大小是512M
注意:一般来说由于redis是一个单线程执行任务,如果一个任务的加载时间过长,可能会导致任务阻塞
🚀1.2基本命令
1.2.1SET
set key value ex 10
=====
set key value
expire key 10
这里的意思就是上面的命令与下面两个命令一起执行的结果是一样的;
如下所示:
解释:flushall的执行就是实现整个键值对的删除,但是这是一个危险命令,要慎重使用
可以发现,在执行这个命令之后,设置10秒过期时间
px 10 其中的ex后的时间是秒,而px的时间是毫秒
nx:key不存在,设置;key存在,不设置返回nil
xx:key存在,设置,key不存在,则不设置返回nil
如下所示:
nx:其实可以理解为一个下载,即没有key才可以发挥作用
xx:可以理解为一个更新,即存在key才可以发挥作用
1.2.2GET
命令如下所示:
get key
对于get来说,只支持字符串类型value,如果是其他类型的话get就会出错;其他的使用在上期的全局变量已经讲解过get的使用了~~~
如上所示,这里我们使用的lpush实现一个集合,然后我们使用get命令去获取,但是很明显可以发现这里报错了error;
1.2.3MSET与MGET
这个命令的主要用处就是一次设计多组键值对
MSET key1 value1 key2 value2
时间复杂度:O(N),这里的N就是key的数量(当前命令中)
上图就是,由于redis是客户端服务器结构的程序,所以需要通过网络来进行通信,网络通信本来就慢,一次传输,接收响应肯定比分两次更加快
要区分大小写哦~~~
上述就是批量获取我们的key的值
1.2.4SETNX
这里的和是上述的分开写差不多是一样的,小编直接操作演示一下吧~~~
直接跳过讲解了
1.2.5SETEX与PSETEX
SETEX:相当于添加了ex,即超时时间,后面的时间单位是秒
PSETEX:相当于添加px,即超时时间,后面的时间单位是毫秒
1.2.6运算操作
具体的主要命令:
incr:针对value + 1
incrby:针对value + n
decr:针对value - 1
decrby: 针对value - n
incrbyflaot:针对value + / - 小数
注意:incr key:操作后的返回值就是 + 1之后的值,并且要求这里的value的编码方式必须是整数类型,64位,8个字节表示的整数
incr操作的key不存在,就会把这个key的value当做0来进行 + 1操作(也可以操作负数)
小编来简单演示演示吧:
这里没有这里没有decrbyfloat,并且上述可以支持正数和负数来进行加减操作;
上述的时间复杂度都是O(1)的~~~;并且因为redis处理命令的时候是单线程模型,多个客户端针对同一个key,进行操作,都不会引起“线程安全问题”;(原子性)
1.2.7append
解释:和我们的java中的append是差不多的,主要是在尾部进行添加
如果key已经存在,并且是一个string类型,那么直接在后面进行拼接就行了,相反append就是相当于是一个SET命令
命令格式:
append key word
返回追加后的字符串的长度(单位是字节,reids不认识字符,只认识字节)
注意:按照utf8编码,一个汉字在utf8字符编码中,一个汉字通常占3个字节
在启动redis的时候,添加--raw这样的raw这样的选项,可以使redis客户端能自动的把二进制数据尝试翻译
可以发现这是以16进制来进行表示的,我们需要查看汉字那么可以在进行客户端连接的时候执行下述命令:
redis-cli --raw
1.2.8getrange与setrange
解释:获取字符串指定范围的字符(子串)
getrange key start end
注意:redis中指定的区间是闭区间~~~
可以支持负数:倒数第几的意思
注意:如果字符串中保存的是汉字,那么此时进行子串切分,很可能就是不完整的汉字,在utf8码表上不知道能查出什么,小编这里就不演示了
setrange key offset value
offset:偏移量,从第几个字节开始进行替换,相当于是下标位置
返回值是替换后的新的字符串的长度;
如果value是一个中文,也可能会出现问题
如果针对不存在的key进行操作,也会进行替换操作,凭空生成字节;把offset之前的内容添加成0x00
执行效果如下所示:
1.2.9strlen
解释:获取字符串的长度
注意这里获取到的字符串的长度单位是字节
在java中char == 2个字节,基于unicode这样的编码方式就能表示中文符号
strlen key
key存放的类型不是string类型报错,key不存在返回0
执行的情况如下所示:
一个字符为两个字节,一个utf8编码的汉字占三个字节~~~
📚️2.string内部编码方式
🚀2.1内部编码
int:8个字节的长整型
embstr:小于等于39字节的字符串,适用于比较短的字符串
raw:大于39字节的字符串,适用更长的字符串
通过object encoding key来查看编码方式
注意:redis存储小数,本质上还是字符串来存储,与整数相比差别很大了;
整数直接使用int(准确来说java就是long类型)
浮点数的算数运算,意味着每次算数运算,都需要吧字符串转化为小数,进行运算后,在转回字符串进行存储
📚️3.string类型应用场景
🚀3.1web服务
整体思路:
应用服务器访问数据时候,先查询redis,如果redis上存在数据,那么直接从redis中读取数据交给服务器,不访问数据库了
如果redis中数据不存在,那么读取mysql,读取的结果返回应用服务器,同时吧这个数据写入到redis中
上述策略存在一个明显问题:
随着时间推移,越来越多的key即数据越来越多的写入我们的redis,内存不够用咋办~~~
解决办法:
1.把数据写给redis的同时,给这个key设置一个过期的时间
2.redis也在内存不足的时候,提供了内存淘汰机制策略
🚀3.2string类型的计数功能
这里我们可以使用redis中incr等命令来执行加减操作
但是:redis并不擅长统计数据
比如:在redis中统计播放量前某某某的视屏
相比之下,mysql统计数据更加方便(这就是为什么要异步写入我们的其他数据源)
异步写入:不是播放一个请求,就立马写入数据,而是持续不断的进行写入的操作;
但是,开发一个成熟的稳定的真实的计数系统,不止计数简单,还有防作弊,按照不同维度计数(例如播放进度),避免单点问题(数据备份和数据冗余),数据持久化等等
🚀3.3会话机制的利用
将session存储到redis中,防止每个服务器各自存储会话,由于负载均衡的情况,不能获取对应客户端的会话
使用redis存储后,应用服务向redis获取客户端的会话,实现了每个服务器的数据共享
这里就是解决cookie和session的分布式的弊端情况,其实这里还可以使用令牌技术,客户端只需要拿着令牌(一个特殊字符串),每个服务器要具备解析的功能,那么也就可以解决上述分布式的问题
📚️4.总结
本文深入剖析Redis中String类型的核心特性和应用场景。首先详述String类型的基本特性,包括二进制安全存储(最大512MB)、丰富的数据格式支持(文本/JSON/二进制等)及基本命令集(SET/GET/MSET等)。重点解析命令参数差异(EX/PX/NX/XX)、原子性操作(INCR/DECR)和字符串处理(APPEND/SETRANGE)。其次揭示内部编码机制(int/embstr/raw)及其转换规则。最后探讨典型应用场景:缓存加速
🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!
💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。
😊😊 期待你的关注~~~