Redis 前记
Redis 操作都是很快的 属于微妙级操作
1.Redis为什么这么快
存储结构?
Redis使用了一个哈希表来存储key - val
一个哈希表就是一个数组,每个数组元素称为哈系桶,所以一个哈希表是多个哈系桶组成的,每个哈系桶保存了键值数据.
那么哈希桶的值是集合类型是怎么存储的? 如:链表和跳表 在redis中val存储的并不是值本身,而是值所在的指针,这样不管 val 是什么都可以通过指针找到.
同时,所有的键值对都存储在哈希表中,也叫这个是全局哈希表.哈希表的好处也是最明显的可以通过O(1)的时间复杂度直接找到键值对,只须计算键的哈希值,能直接查找到哈系桶的位置.
这个查找过程依赖于计算的哈希值,与数据量并没直接关系,也就是不管是10W 还是100W 查找速度都是一样的.
那为什么在数据量大的时候查找速度会变慢?
在往哈系桶插入数据是,两个key的哈希值正好落到了同一个哈系桶上,这就出现了哈希冲突
那哈希冲突又是怎么解决的,Redis解决哈希冲突的方式是链式哈希 ,就是哈系桶中的数据用链式的方式来存储数据.
问题又来了,大家都知道链式查找数据都是通过指针逐一查找,当数据大时,查找速度会很慢,且数据再大,还是会出现哈希冲突
所以Redis会对哈希表进行rehash操作(渐进式操作)
在Redis中默认有两张hash表 hash1 和hash2 ,当插入数据默认使用hash1 hash2没有分配空间 当数据增多,会给hash2分配空间(hash1 * 2 空间大小)
1.给hash2分配更大的空间
2.将hash1中的数据映射到hash2中
3.释放hash1中的空间
在第二步中涉及到了大量的数据copy 很容易造成Redis堵塞,后面的请求无法执行, Redis就会执行rehash操作,在每次客户端请求处理完 就会将hash1 从第一个索引开始将对应的所有数据copy到 hash2,那如果客户端没有请求进来就不执行吗? 在redis中会有定时逐步copy数据,这就一次的copy大开销分摊到多次请求中.
那么Redis有哪些数据类型?
String(字符) List(列表) Hash(哈希) set(集合) Sorted set(有序集合)
底部存储有六种类型(动态字符,整数数组,双向链表,哈希,压缩列表,跳表)
在Redis底层中 数组和压缩列表 查找时间复杂度并没有很大优势,为什么Redis会采用?
redis快都知道是在内存上操作
数组和压缩列表有很好的内存利用率,这两个都是非常紧凑的数据结构,相比链表占用的内存较小,Redis是内存数据库,有大量数据,在内存要尽量提高内存利用率
数组对CPU高速缓存支持更友好,所以Redis在设计时,集合数据元素较少情况下,默认采用内存紧凑排列的方式存储,同时利用CPU高速缓存不会降低访问速度。