- 基于内存
- 数据结构简单、高效
- 利用 IO多路复用监听事件、事件驱动
- 首先必须明确,
redis
单线程指的是网络请求模块使用了一个线程,其他模块有的用的是多线程,并不是一个线程完成了所有功能。 - 原理上,其采用了利用
epoll
的多路复用特性,因此可以采用单线程处理其网络请求。 6.0
以后,使用了多线程并行处理IO读写事件(网络连接仍然用一个线程处理)。- 这种做法和
Go
的http
库异曲同工,netpoll
里只用一个协程处理网络连接,但对连接里请求的读写,仍然是每个连接起两个协程分别负责其读写。
- 这种做法和
- 针对热点数据进行缓存
- 对于特定限时数据的存放
- 针对带热点权值数据的排序
- 分布式锁
redis
处理网络请求采用单线程模型,而memcache
采用多线程的方式redis
支持数据持久化,memcache
不支持redis
支持的数据格式比memcache
更多(一般选型都是这个原因)
缓存穿透指缓存和数据库均没有需要查询的数据,查询穿透到DB,使数据库压力过大。
- 前置过滤
- 在数据库操作访问前进行校验,对不合法请求直接返回
- 每天定时使用布隆过滤器重置所有
key
的集合,先判断key
在不在,再查redis / DB
- 对于经常被访问的,并且数据库没有的
key
,缓存该key
的值为null
。不过这个得设较短的过期时间,防止数据长时间不一致。
高频访问的key过期失效,导致缓存瞬间被击穿,打到数据库
解决方法
- 设置热点数据永远不过期。
singleflight
:从数据库加载到缓存时加锁。
缓存雪崩指缓存中一大批数据同时到过期时间。导致大量请求打到数据库
解决方法
- 缓存数据设置随机过期时间,防止同一时间大量数据过期。
- 设置热点数据永远不过期。
是指因为网络问题,导致 master
节点未宕机的情况下,sentinel / 其余master
因为连接不上 master
,所以将 slave
提升为 master
。此时存在两个不同的 master
节点。
如果客户端还在基于原来的 master
继续写入数据,那么新的 master
节点将无法同步这些数据,当网络问题解决之后,原先的 master
被降为 slave
,此时再从新的 master
中同步数据,将会造成大量的数据丢失。
设置 min-slaves
参数,这样向旧的主节点写数据时会因无法同步给从节点而失败。客户端收到错误时应重新查找主节点
- 数据类型更多:Redis支持多种数据类型,如字符串、列表、哈希、集合、有序集合等,而Memcached只支持简单的键值对。
- 持久化:Redis支持将数据持久化到磁盘,即使在服务器重启后也可以恢复数据,而Memcached不支持数据持久化。
- 高可用:Redis支持主从复制和集群模式,可以提供更高的可用性和可扩展性。
- 更丰富的功能:Redis支持事务、发布/订阅、Lua脚本等更多的功能,可以满足更多的应用场景。
- 性能差不多(因为都是读写内存,一般瓶颈在网络)
在 Redis 中,时间复杂度最高的命令是 KEYS
命令。 KEYS
命令是用来查找与指定模式匹配的键名。它的时间复杂度为 O(N),其中 N 是键空间的大小。因为它需要遍历整个键空间来查找符合条件的键名,所以在非常大的键空间中使用 KEYS
命令可能会导致 Redis 阻塞一段时间,从而降低 Redis 的性能。
如果想要查找符合某种模式的键名,建议使用更高效的命令,如 SCAN
命令。SCAN
命令可以在时间和空间上更高效地获取符合指定模式的键名。使用 SCAN
命令时,可以通过游标(cursor)来逐步遍历整个键空间,避免一次性遍历导致的性能问题。
其他命令一般都是O(1)、O(lgN) 的时间复杂度