在c#或java,在特定的一些场合下,比如存储固定长度的键且键连续的情况下,我们很容易就想到直接用数组来存储连续的值,然后通过索引来快速获取;这样既节省了链表中每个节点的指针所占用的内存空间,也能提高 random access的能力;
redis有五种数据类型string、hash、list、set、sorted set
以上特定情景如果我们list来存储的话,可以利用lrange、lpop、rpop、和blocked版本的操作来模拟, 但是总归还是有节点间联系所带来的开销;
如果用string来模拟的话,就可以利用setrange,getrange等获取和设置字符串指定索引位置的值来模拟数组了,并且节约了指针的开销;
但是这种方法有几个限制:
- redis的string类型值容量上限为512MB,如果超过需要自己进行分片处理
- 每个节点的值长度必须一致,且id连续,不然不能正确的确定每个节点的索引位置
简单的测试下:
#list:
for i in range(1,1000):
conn.rpush('list',10)
#string:
str = ''
for i in range(1,1000):
str += ' 10'
conn.set('str',str)
利用github上一个可以分析redis单个key占用内存的工具rdbtools可以看到这两个key占用的内存差距还是非常大的
网友评论