总结参考Redis开发与运维
1.Redis数据类型有几种,对应的内部实现分别是什么。
redis有string,hash,list,set,zset(sorted set)五种数据类型,对应的内部实现如下。
string |
embstr、int、raw |
hash |
hashtable、ziplist |
list |
linklist、ziplist |
set |
hashtable、intset |
zset(sorted set) |
skiplist、ziplist |
查看数据类型value对应的数据类型可以type key命令,查看内部编码可以使用object encoding key命令。
2.为什么要对每种数据类型设计多个内部编码实现。
第一:redis开发出了新的内部编码实现只需要更改redis的代码就可以了,使用者不需要去更改代码,只需要升级redis版本就可以使用新特性。
第二:可以在不同场景下发挥每种内部编码各自的优势,根据不同的情况采用不同的内部编码实现,从而提高redis的性能。
3.Redis和memcached相比有什么异同。
第一:memcached只支持key/value这种格式的数据,redis支持五种数据类型的数据。
第二:两者在运行时数据都是存在内存中的,但是memcached不能持久化数据到硬盘,而redis支持数据持久化到硬盘。
第三:内存管理机制不一样,memcached会对传过来的数据进行计算,选择一个最适合的chunk进行保存,redis会把要保存数据的size存在内存块的头部。
第四:性能差距,因为redis只使用单核,memecached使用多核。在保存数据时平均到每一个核的性能会优于memcached。数据大小高于100k时memcached性能更好。
4.redis为什么快。
第一:redis是完全基于内存的,所以存取数据非常快速。
第二:数据结构简单,内部对同一个数据类型会有多种实现,根据具体情况会自动选择合适的数据类型。
第三:采用单线程架构,省去了不同线程之间来回切换的开销。
第四:采用多路IO复用模型,非阻塞IO。redis的事件处理机制,避免了网络IO带来的性能损耗。
5.为什么redis要设计成单线程架构。
因为redis的性能瓶颈主要是因为内存大小,网络带宽等,而不是单个CPU的计算性能瓶颈。但是单线程的架构没办法使用使用多核CPU的性能,这种情况可以在一台多核CPU的机器上启动多个redis来解决。
6.redis怎么遍历键,keys命令和dbsize在使用上有什么需要注意的地方。
redis遍历键可以使用keys命令和scan命令。keys命令支持遍历全部键,也可以指定匹配规则来遍历。scan命令可以只遍历一部分键,通过多次执行来遍历全部的键。因为keys命令在数据量很大的情况下可能会造成阻塞,这时可以使用scan命令来遍历,因为scan命令参数更丰富,使用起来也更灵活。keys命令和dbsize命令都可以拿到redis键总数。keys是通过查询全部的key来计算总数,dbsize命令在计算总数时不回去遍历所有的key,而是直接获取redis中内置的键总数变量。
6.redis各个数据类型的值最大容量是多大。
数据类型 |
存储容量 |
string |
512M |
list |
4294967295 |
set |
4294967295 |
zset |
4294967295 |
hash |
4294967295 |
7.redis持久化有几种方式,有什么区别。
redis持久化数据到硬盘有RDB和AOF两种方式。触发RDB的方式分为手动触发和自动触发两种方式。默认使用RDB方式进行持久化。
RDB:
将内存中的数据以快照的方式写到二进制文件中,默认文件名是dump.rdb。RDB方式每次保存数据都是全量保存,会将所有数据都持久化到硬盘中。
手动触发针对应save和bgsaver命令。save命令会阻塞当前redis服务直至RDB完成,bgsave命令会fork创建子进程进行持久化操作,RDB完成后进程关闭。bgsave命令会在创建子进程的时阻塞服务。
自动触发RDB的情况如下:
1.使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改 时,自动触发bgsave。 |
2.如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点。 |
3.执行debug reload命令重新加载Redis时,也会自动触发save操作。 |
4.默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则 自动执行bgsave。 |
AOF:
会将每一次操作的数据都以日志的形式记录到硬盘中,默认文件名是appendonly.aof。使用AOF需要设置appendonly yes
AOF提供的同步策略有以下几种,由appendfsync参数控制
always |
命令写入aof_buf后调用系统fsync操作同步到aofwen文件中,fsync完成后线程返回 |
everysec |
命令写入aof_buf后调用系统write操作,write完成后线程返回。fsync同步文件操作由专门线程每秒调用一次 |
no |
命令写入aof_buf后调用系统write操操作,不对aof文件做fsync操作,同步硬盘操作由操作系统负责,通常同步周期最长30秒 |
因为always同步频率太高,硬盘速度回严重影响性能,所以一般不建议使用。everysec是默认的配置,理论上只会丢失一秒的数据,但是由于每次fsync的时间是不确定的,如果这次的fsync操作没有执行完就会阻塞,下一个fsync操作就需要等待,这种情况下丢失数据很可能就不止一秒钟的数据了。所以实现高可用应该两种持久化方式同时使用(此处不考虑集群环境)。
8.redis修改配置会实时生效吗。
一般来说不用重启,会实时生效。redis2.2版本开始支持从RDB和AOF或其他持久化方式不用重启。但是如果升级redis这种改动还是需要重启的。