为什么使用 Redis
- 速度快,因为数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是 O1)
- 支持丰富数据类型,支持 string,list,set,Zset,hash 等
- 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
- 丰富的特性:可用于缓存,消息,按 key 设置过期时间,过期后将会自动删除
Redis的常用数据类型有哪些
Redis是一个基于内存的键值对数据库,它的键都是字符串类型,而值的部分支持5种数据类型,每种类型特点不一样
- string:字符串类型,可以存储普通字符串、JSON字符串,也可以存储对象系列化之后的字符串
- hash:哈希类型,类似于Java中的HashMap,比较适合存储对象
- list:列表类型,底层是一个顺序链表,可以从两端添加或移除元素,元素是有序的,可重复的
- set:无序集合,没有重复元素
- zset:有序集合,没有重复元素,且集合中每个元素关联一个分数,可以根据分数进行排序
跳表你了解吗
跳表(SkipList)首先是链表,但与传统的链表相比有几点差异:
- 跳表结合了链表和二分查找的思想
- 元素按照升序排列存储
- 节点可能包含多个指针,指针跨度不同
- 查找时从顶层向下,不断缩小搜索范围
- 整个查询的复杂度为 O ( log n )

Redis数据类型Sorted Set使用了跳表
Redis 可以用来做什么
- 缓存
- 排行榜
- 分布式计数器
- 分布式锁
- 消息队列
- 分布式 token
- 限流
Redis 为什么快
- (内存操作)完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。
- (单线程,省去线程切换、锁竞争的开销)采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
- (NIO 的 IO 多路复用模型)使用多路 I/O 复用模型,非阻塞 IO;这里"多路"指的是多个网络连接,"复用"指的是复用同一个线程
解释一下I/O多路复用模型
嗯~~
- I/O多路复用是指利用单个线程来同时监听多个Socket ,并在某个Socket可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。目前的I/O多路复用都是采用的epoll模式实现,它会在通知用户进程Socket就绪的同时,把已就绪的Socket写入用户空间,不需要挨个遍历Socket来判断是否就绪,提升了性能。
- 其中Redis的网络模型就是使用I/O多路复用结合事件的处理器来应对多个Socket请求,比如,提供了连接应答处理器、命令回复处理器,命令请求处理器;
- 在Redis6.0之后,为了提升更好的性能,在命令回复处理器使用了多线程来处理回复事件,在命令请求处理器中,将命令的转换使用了多线程,增加命令转换速度,在命令执行的时候,依然是单线程
Redis 过期删除策略
常用的过期数据的删除策略就两个:
- 惰性删除:当客户端尝试访问一个键时,Redis会在访问时检查键是否过期,如果过期则执行删除操作。这样对 CPU 最友好,但是可能会造成太多过期 key 没有被删除。
- 定期删除:每隔一段时间抽取一批 key 执行删除过期 key 操作。并且Redis底层会通过限制删除操作执行的时长和频率来减少删除操作对 CPU 时间的影 响。
定期删除对内存更加友好,惰性删除对 CPU 更加友好。两者各有千秋,所以 Redis 采用的是定期删除+惰性/懒汉式删除。但是仅仅通过给 key 设置过期时间还是有问题的。因为还是可能存在定期删除和惰性删除漏掉了很多过期 key 的 情况。这样就导致大量过期 key 堆积在内存里,然后就 Outofmemory 了。
怎么解决这个问题呢?答案就是:R

最低0.47元/天 解锁文章
38万+

被折叠的 条评论
为什么被折叠?



