目录
- 1、Redis中Key的结构
- 2、Redis的多线程
- 2.1、Redis的多线程模型
- 2.2、Redis多线程的配置
- 3、Redis内存淘汰算法
- 3.1、淘汰策略和算法
- 3.2、配置
1、Redis中Key的结构
redis
的所有value
都是以redisObject
的结构存储, 具体结构如下。我们可以从中知道一个key
有哪些元数据,以后做高级分析或许能用上。
- 数据类型:就是
string,set,hash
之类的。 - 内部编码类型:
redis
的底层数据实现。比如List
有两种实现方式双向链表和压缩列表,内部编码类型会指明是哪种实现方式。 - LRU记时时钟:记录着对象最后被访问的时间。可以通过
object idletime key
获取,返回一个整数,数值越大,则离上次访问的时间越久。 - 引用计数器:表示有多少个指针指向表示当前
key
。这里隐含着redis
的内存回收算法是引用计数法,当引用计数器位0时,那该对象就会被回收。 - 数据指针:指向对应的
value
而key
则是这样的结构
2、Redis的多线程
2.1、Redis的多线程模型
redis
在6.0
之后才开始支持多线程,但它的多线程又不像其它系统的多线程那样复杂。下面就详细讲解redis
是如何实现多线程。
Redis
IO是典型的多路复用模型
客户端的每个连接就是一个socket
,这些socket
会先汇总到一个叫IO多路复用器的地方。
IO多路复用器的实现比较复杂,不同的操作系统有不同的实现方式。比如Linux
用epoll
,Solaris 10
用evport
等。这里不细说。
IO多路复用器可以看成是一个队列,socket
请求在里面排队,逐个被送到文件事件分派器。
文件事件分配器会根据请求的类型,将请求交给不同的事件处理器。
从文件事件分分派器开始,处理变成了多线程。
在linux
一切皆文件,所以文件事件分派器将socket
请求交给各个事件处理器时实际上是涉及到文件IO,所以这里其实有优化的空间,这部分的工作就支持多线程。
之后命令解析之后,还需要去执行这些命令,但这里又回到了单线程,这就保证了redis
的线程安全性,因为执行的时候仍然是单线程。
2.2、Redis多线程的配置
# turn on multi-thread
io-threads-do-reads yes
# numbers of threads. Recommond 2or3 if core number of CPU is 4,6or7 for 8-core。
io-threads 4
3、Redis内存淘汰算法
3.1、淘汰策略和算法
当redis
使用的内存达到上限时,redis
就会根据配置的内存淘汰策略删除一些内存。当然也可以配置不删除,但是redis
就不支持插入操作,只能查询和删除。
redis
有如下的淘汰策略,概括来说就是根据LFU(Least Frequently Used,使用频率最少)或者LRU(Least Recently Used,最旧使用)来进行删除或者加个过期时间。具体如下。
# volatile-lru -> 给最久没有使用的key加上过期时间
# allkeys-lru -> 直接删除最久没使用的一些key
# volatile-lfu -> 给使用最不频繁的一些key加上过期时间
# allkeys-lfu -> 直接删除使用最不频繁的一些key
# volatile-random -> 随机给一些key加上过期时间
# allkeys-random -> 随机直接删除一些key
# volatile-ttl -> 直接删除一些快过期的key
# noeviction -> 什么都不删,但是write操作会报错
#
# LRU means Least Recently Used
# LFU means Least Frequently Used
我们继续了解redis
是如何实现这些算法的。
LFU
:LRU
:一般的LRU
算法实现是通过对所有的key维护一个链表,一个key被用到了,那就将这个key移到链头。这样链尾就是最久没使用的key。
但这样的消耗较大,从链表中找到一个元素时间是o(n)
,元素放到链头时间是o(1)
。对于redis
来说o(n)
的时间是不能容忍的,所以redis
是通过近似的算法来实现LRU
。redis
的key存储着上次访问的时间。redis
每次选5个key,然后选择上次访问时间最久的那个key删除,就这样不断循环。每次选择的样本个数可通过maxmemory-samples
配置,这个值越大,效果越精确,越能选出最久没使用的key,同时消耗也越大;值越小则所有效果都相反。
3.2、配置
# redis max memory. when actual used memory reach this threshold,
# redis will delete some keys or don't support adding keys.
# it depends on the maxmemory-policy. Unit is bytes. 0 by default means no limit.
maxmemory <bytes>
# The way redis choose keys to delete. noeviction by default means never deleting keys.
maxmemory-policy noeviction
# LRU is a approximate algorithm. It will check five keys by default radomly then delete the least used one.
# We can change the number of samples through configuartion.
maxmemory-samples 5