共计 1700 个字符,预计需要花费 5 分钟才能阅读完成。
这篇文章主要介绍 redis 字符串类型的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
我们都知道 redis 是采用 C 语言开发,那么在 C 语言中表示 string 都是采用 char[] 数组的,然后你可能会想,那还不简单,当我执行如下命令,肯定是直接塞给 char[] 数组的。
如果你真的这么想的话,会有几个问题就要过来砍你了,先我们来找一个 redis 手册,http://doc.redisfans.com/
第一:如果你每次都执行 Append 函数,那是不是 redis 的 char[] 每次都需要再次扩容,这样是不是每次都是耗时操作呢?
第二:如果你每次执行 String 中的 StrLen,那 redis 底层是不是每次都要遍历 char 数组来得到结果呢?
一、探索 Redis 中的 String 是如何存储的
根据上面说的那些小情况,所以 redis 的作者没有那么傻,正常的逻辑应该是在 char[] 数组的层面上自己再来封装一层。
1. SDS 结构体
在 redis 里面是采用 SDS(simple dynamic string) 来封装 char[] 的,这个也是 redis 存储的最小单元,下一个问题就是哪里能看得到呢?我在 wget 压缩包的时候,里面就有 redis 源码啦,据说还只有 3w 多行,这就告诉我们,有什么问题,自己动手丰衣足食,对吧,为查找方便,我就把 redis 的源码拖到 window 上用 vs 打开,接下来我们看看 SDS 长成啥样???
可以看到它是定义在 redis 源码中的 sds.h 源文件中的,你可能会奇怪,这三个属性是干嘛用的???下面我简单说一下。
1 len:标记 char[] 的长度, 有点类似我们 C# 中 List 的 length 一个意思。
2 free: 标记 char[] 中未使用的元素个数,就是有几个空坑的意思。
3 buf[]: 存放元素的坑,不一定和元素的实际个数相等,比如前面说的 cnblogs。也有可能是 [c][n][b][l][o][g][s][/0][][][]。
二、探索 Redis 对象 (RedisObject)
前面说到的 SDS 仅仅是 char[] 数组的封装,并不能标识 redis 中的 5 大类型,所以可想而知,redis 还需要在 SDS 上面进行封装,所以就有了接下来的
RedisObject 对象,我们先看看它长成啥样。
可以看到 RedisObject 是在 redis.h 源代码文件中的,下面我简单说说 type 和 ptr 属性,详细的东西在后续说。
1 type 这个就是用来标识 redisObject 是哪种类型,既然是哪种类型,肯定就有一个类型枚举,对吧,肯定有了,给你看看。
2 *ptr 可以看到这玩意还是个指针类型,它所指向的内存地址,你应该也知道了,就是所谓的 SDS 枚举类型。
好了,到现在你可以整合一下博客开始处的:
127.0.0.1:6379 set name cnblogs
127.0.0.1:6379 get name
cnblogs
127.0.0.1:6379
针对上面的 set 命令,redis 其实会创建两个 RedisObject 对象,键的 RedisObject 和值的 RedisOjbect 其中它们的 type=REDIS_STRING,也就都是字符串对象类型,其中的 SDS 分别存储的就是 name 和 cnblogs 的字符咯,好了,大概就这样了。
三、挑选几个有意思的命令
1. incr,incrby,decr,decrby
这四个命令有点像 C# 中的 Interlocked 类的方法,如果你了解 Interlocked,你应该就知道下面有各种原子自增,自减等等方法,如下图:
redis 这个自增有什么好处呢?我觉得用这个生成订单号还是蛮好的,我记得在携程的时候,生成订单号是专门的一个 OrderIDDB 中的 func 函数来生成的,这样 OrderID 是不依赖于任何业务库的,然后我们就可以相对方便的分库分表了,现在用 redis 这样做也挺好的。
其他的一些命令也没什么好说的了,大家可以对照 redis 手册看一看就好了。
以上是“redis 字符串类型的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注丸趣 TV 行业资讯频道!