Redis与Memcached区别:
两者都是非关系型数据库。主要有以下不同:
数据类型:- Memcached仅支持字符串类型。
- redis支持:String,List,set,zset,hash 可以灵活的解决问题。
- Memcached不支持持久化。
- Redis采用两种持久化策略:RDB快照和AOF日志。
- Mencached不支持分布式,只能在客户端使用一致性hash来实现分布式存储,这种方式在存储和查询时都需要在客户端先计算一次数据所在的节点。
- redis cluster实现了分布式的支持。
- redis中,并不是所有数据都一直存储在内存中,可以将一些很久没用的value交换到磁盘,而memcached数据则候会一直在内存中。
- memcached将内存分割成特定的块进行存储,以完全解决内存碎片化的问题,但是这种方式使得内存利用率不高,如块大小128bytes,只存储了100bytes的数据,那么剩下的28bytes就浪费掉了。
键的过期时间:
redis可以为每个键设置过期时间,当键过期时,自动删除该键。对于散列表这种容器,只能为整个键设置过期时间(整个散列表),而不是为键里面的单个元素设置过期时间。
设置键的生存时间:- expire: 指定秒
- pexpire: 指定毫秒
127.0.0.1:6379> set key hello
OK
127.0.0.1:6379> expire key 1
(integer) 1
127.0.0.1:6379> get key
(nil)
127.0.0.1:6379> hset hashkey key1 1
(integer) 0
127.0.0.1:6379> hget hashkey key1
"1"
127.0.0.1:6379> expire hashkey 1
(integer) 1
127.0.0.1:6379> hget hashkey key1
(nil)
127.0.0.1:6379> zadd zset 0 key1 1 key2
(integer) 0
127.0.0.1:6379> zrange zset 0 -1
1) "key1"
2) "key3"
3) "key2"
127.0.0.1:6379> expire zset 1
(integer) 1
127.0.0.1:6379> zrange zset 0 -1
(empty list or set)
- expireat:秒精度
- pexpireat:毫秒精度
过期键的删除策略:
定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键过期时间来临时,立即执行对键的删除操作。
- [ ] 优点:对内存是友好的,可以保证过期键会尽可能快被删除,并释放过期键所占用的内存。
- [ ] 缺点:对CPU不友好,在过期键较多的情况下,删除键的操作会占用相当一部分的CPU时间,在内存不紧张但CPU紧张的情况下,将cpu时间用在删除与当前任务无关的过期键上,无疑会对服务器的响应时间和吞吐量造成影响。
此外,定时器需要使用redis服务器的时间事件,时间事件的实现方式为无序链表,查找一个事件的事件复杂度为O(N),因此创建大量的定时器不现实。
仅在程序取出键时才进行过期检查
- [ ] 优点: CPU友好,不会花费额外的时间。
- [ ] 缺点:对内存不友好,会造成内存泄漏。
每隔一段时间执行一次删除过期键操作,并通过限制删除操作执行的时长和频率来减少对CPU时间的影响。
数据淘汰策略:6种
可以设置内存最大使用量,当内存使用超出时,施行数据淘汰策略。
作为内存数据库,出于对性能和内存消耗的考虑,redis的淘汰算法实际上并未针对所有key,而是
抽样一小部分并且从中选出被淘汰的key。使用reids缓存数据时,为提高缓存命中率,需要保证缓存都是热点数据。可以将内存最大使用量设置为热点数据占用的内存量,然后启用allkeys-lru淘汰策略,将最近最少未使用的数据进行淘汰。redis4.0 版本后引入了volatile-lfu和allkeys-lfu淘汰策略,LFU策略通过统计访问频率,将访问频率最小的键值进行淘汰。 持久化:
redis是内存型数据库,为了保证数据在断电后不会丢失,需要将内存中的数据持久化到硬盘上。
RDB持久化:
- 将某个时间点的所有数据都存放到硬盘上。
- 可以将快照复制到其他服务器从而创建具有相同数据的服务器副本。
- 如果系统方法故障,将会丢失最后一次快照后的数据。
- 如果数据量很大,保存快照时间会很长。
- [ ] redis命令
- save:生成RDB文件,会阻塞服务器进程,知直到RDB文件创建完毕。
- bgsave: 派生(fork)一个子进程,然后由子进程负责创建RDB文件,父进程继续处理命令请求。
- 使用save相关配置,如“save m n”。表示m秒中对数据集进行n次修改,就触发bgsave。
- 如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件发送给从文件。
- 执行debug reload 命令重新加载redis时,自动触发save操作。
- 默认情况下执行shutdown命令时,若没有开启AOF持久化功能则自动执行bgsave。
- [ ] 优点: 适用于备份,全量复制等场景。恢复数据远快于AOF方法。
- [ ] 缺点:没办法做到实时持久化/秒级持久化。 RDB使用特定二进制格式,redis演化中有多个RDB版本,存在版本不兼容情况。
AOF 持久化:
将写命令添加到AOF文件的末尾(append Only File)使用AOF持久化需要设置同步选项,从而保证写命令什么时候会被同步到磁盘文件上。这时因为对文件进行写入并不会,马上将内容同步到磁盘上,而是先存储到缓冲区,然后由操作系统决定什么时候同步到磁盘。有以下同步方式:
- always:每个写命令都同步。严重影响服务器性能
- everysec:每秒同步一次。可以保证系统崩溃时只丢失一秒左右的数据,每秒执行一次对性能几乎没影响。
- no:让操作系统决定,最长30秒。不能带来太多的性能提升,但是会增加系统崩溃时数据丢失的数量。
随着服务器写请求的增多,AOF文件会越来越大。redis提供了一种将AOF重写的特性,能够去除AOF文件中冗余的写命令。
- 进程中已经超时数据不再写入文件。
- 旧的AOF文件含有无效命令。
- 多条命令合并(对同一键值的更新)。