Redis 数据对象和数据结构
redis 中数据对象如下,这些都是基于数据结构实现的对象。
- string 字符串,二进制安全的字符串
- list 列表,按插入顺序排序的字符串元素的集合
- hash 哈希,由field和关联的value组成的map
- set 集合,不重复且无序的字符串元素的集合。
- sorted sets 有序集合,但是每个字符串元素都关联到一个叫score浮动数值(floating number value)。里面的元素总是通过score进行着排序, 按照升序排列
- bitmaps 位图
- hyperLoglogs:估计一个 set 中元素数量的概率性的数据结构
- geospatial 地理空间
1 总览
常用的数据对象一般是5种.
- string
- list
- hash
- set
- sorted set
2 redis 设计结构
Redis 是 K-V 型数据库,那么为了实现从键到值的快速访问,Redis 使用 hash 表来保存所有的键值对,哈希桶中的元素保存的并不是值本⾝,⽽是指向具体值的指针。这也就是说,不管值是 string,还是集合类型,哈希桶中的元素都是指向它们的指针
hash 冲突解决
Redis会对哈希表做 rehash 操作。rehash 也就是增加现有的哈希桶数量,让逐渐增多的entry元素能在更多的桶之间分散保存,减少单个桶中的元素数量,从⽽减少单个桶中的冲突。
常规rehash
Redis默认使⽤了两个全局哈希表:哈希表1和哈希表2。⼀开始,当你刚插⼊数据时,默认使⽤哈希表1,此时的哈希表2并没有被分配空间。随着数据逐步增多,Redis开始执⾏
rehash,这个过程分为三步:
- 给哈希表2分配更⼤的空间,例如是当前哈希表1⼤⼩的两倍;
- 把哈希表1中的数据重新映射并拷⻉到哈希表2中;
- 释放哈希表1的空间。到此,我们就可以从哈希表1切换到哈希表2,⽤增⼤的哈希表2保存更多数据,⽽原来的哈希表1留作下⼀次rehash扩容备⽤。
但是第⼆步涉及⼤量的数据拷⻉,如果⼀次性把哈希表1中的数据都迁移完,会造成 Redis线程阻塞,⽆法服务其他请求。此时,Redis就⽆法快速访问数据了
渐进式 rehash
在第⼆步拷⻉数据时,Redis仍然正常处理客⼾端请求,每处理⼀个请求时,从哈希表1中的第⼀个索引位置开始,顺带着将这个索引位置上的所有entries拷⻉到哈希表2中;等处理下⼀个请求时,再顺带拷⻉哈希表1中的下⼀个索引位置的entries。这样就巧妙地把⼀次性⼤量拷⻉的开销,分摊到了多次处理请求的过程中,避免了耗时操作,保证了数据的快速访问。