目录
数据类型
1.字符串:String(可以操作数字)
2.散列:hashes
3.列表:lists
4.集合:sets
5.有序集合:sorted sets
6.bitmaps
7.hyperloglogs
8.地理空间(geospatial) 索引半径查询
redis的过期策略以及内存淘汰机制
redis采用的是定期删除+惰性删除策略。
-
为什么不用定时删除策略
定时删除需要维护大量的定时器来监听key的过期,虽然可以及时释放资源但是大量的定时器会十分消耗资源 -
redis采用的是定期删除+惰性删除策略。
redis默认每100ms检查是否有过期的key,存在则删除(每100ms并不是检查所有的key而是随机抽取进行检查),会存在key过期了但是没抽取到的。
惰性删除是:当获取某个key的时候会检查过期时间,过期了则删除,还是存在问题(当一个key过期了,没检查到但是一直也没访问)
内存淘汰机制
配置文件 # maxmemory-policy volatile-lru 属性
- noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。应该没人用吧。
- allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。推荐使用,目前项目在用这种。
- allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key
- volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用。不推荐
- volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。依然不推荐
- volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。不推荐
如果没有设置过期时间的key, 不满足先决条件(prerequisites); 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致。
redis和数据库双写一致性问题
一致性问题是分布式常见问题,还可以再分为最终一致性和强一致性。数据库和缓存双写就必然存在不一致的问题。如果对数据有强一致性要求就直接使用数据库不使用缓存了。
在使用数据库和redis是更新删除 先操作数据库在更新删除缓存。如果是删除,缓存删除失败可以发一个消息队列,来补偿一下
如何解决redis的并发竞争key问题
同时多个客户端去set同一个key
解决方案:
- 如果数据没使用分片
用watch命令,watch每次操作时都对值进行cas操作,如果已经处理过则不在进行处理 - 如果使用了分片
- 如果对key没有顺序要求
用分布式锁,抢到锁就操作 - 对顺序有要求
- 可以使用时间戳, 就是在写入时保存一个时间戳,写入前先比较自己的时间戳是不是早于现有记录的时间戳,如果早于,就不写入了。
- 使用消息队列来进行串行化处理。这在高并发场景中是一种很常见的解决方案。
- 常用的解决方法:
乐观锁,注意不要在分片集群中使用
分布式锁,适合分布式系统环境
时间戳,适合有序场景
消息队列,串行化处理
redis数据分片
需要redis存储海量的内存数据,使用单台redis不能满足用户的需求,所以可以采用Redis分片机制实现数据存储
注意事项:
如果有多台redis,则其中的数据都是不一样的…
一致性HASH算法
一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。
在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题
原理说明
- 常规hash由多少位16进制数组成 8位16进制数组成 2^32次方
- 如果对相同的数据进行hash计算问结果是否相同? 结果必然相同.
特性一平衡性
- 平衡性是指hash的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题.
实现平衡性的方案: 引入虚拟节点
特性二单调性
- 单调性是指在新增或者删减节点时,不影响系统正常运行 。
特点:在进行数据迁移时,要求尽可能小的改变数据.
特性三分散性
- 分散性是指数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据 。
俗语: 鸡蛋不要到放到一个篮子里
哈希槽
一个 redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个数据都属于这16384个哈希槽中的一个。集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽。集群中的每一个节点负责处理一部分哈希槽。
slot返回有关哪个集群插槽映射到哪个redis实例的详细信息。该命令适用于redis集群客户端库实现,以便检索(或在收到重定向时更新)将集群散列槽与实际节点网络坐标(由ip地址和tcp端口组成)关联的映射,以便在接收到命令时,可以将其发送到命令中指定的键的正确实例。
redis的特点
Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过10万次读写操作,是已知性能最快的Key-Value DB。
Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB,不像 memcached只能保存1MB的数据
使用redis有哪些好处
(1)速度快,因为数据存在内存中
(2)支持丰富数据类型,支持string,list,set,sorted set,hash
(3)支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
(4)丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
redis相比memcached有哪些优势
(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
(2) redis的速度比memcached快很多
(3) redis可以持久化其数据
Memcache与Redis的区别都有哪些?
(1) 存储方式 Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。Redis有部份存在硬盘上,这样能保证数据的持久性。
(2 )数据支持类型Memcache对数据类型支持相对简单。Redis有复杂的数据类型。
(3) 使用底层模型不同它们之间底层实现方式以及与客户端之间通信的应用协议不一样。Redis直接自己构建了VM机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
Redis持久化
-
RDB(快照)
Redis把数据快照存放在磁盘上的二进制文件中,文件名为dump.rdb手动持久化
save 阻塞
bgsave 非阻塞forks 开启子进程开始持久化数据
使用copy-on-write技术 -
AOP
Append-only(保存的是执行的命令)
需要用重写来减少文件大小
主从复制
1 全量同步
Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:
1)从服务器连接主服务器,发送SYNC命令;
2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
2 增量同步
Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
4 注意点
如果多个Slave断线了,需要重启的时候,因为只要Slave启动,就会发送sync请求和主机全量同步,当多个同时出现的时候,可能会导致Master IO剧增宕机。
缓存雪崩
同一时间大面积key失效,这个时候来了一波请求,结果都到了数据库导致数据库异常。
解决方案
- 给缓存的失效时间加上一个随机值,避免集体失效
缓存穿透
请求缓存中不存在的数据,导致所有请求都到数据库上,从而导致数据库连接异常。
解决方案:
- 采用布隆过滤器
- 采用异步更新策略:无论key是否存在都直接返回。value值中维护一个缓存失效时间,如果过期异步起一个线程去读数据库,更新缓存。
缓存击穿
一个key过期了,然后有大量请求进来获取数据导致请求都到数据库导致数据库异常
解决方案:
- key过期请求加互斥锁