Redis相关

1、Redis的数据类型
  • String:
    格式:set key value
    string是二进制安全的,可包含任何数据,如jpg或序列化的对象 。string是Redis最基本的数据类型,一个键最大能存储512MB。
  • List:
    list是简单的字符串列表,按插入顺序排序。可以添加一个元素到list的头部(左边)或尾部(右边)。
    格式:lpush name value //在key对应list的头部添加字符串元素
    格式: rpush name value //在key对应list的尾部添加字符串元素
    格式: lrem name count //删除key对应list中count个和value相同的元素
    格式: llen name //返回key对应list的长度
  • Hash:
    格式: hmset name key1 value1 key2 value2
    hash是一个键值(key=>value)对集合,是一个string类型的key和value的映射表,适合用于存储对象。
  • Set:
    格式: sadd name value
    Set是string类型的无序集合,通过哈希表实现,添加、删除、查找的复杂度都是O(1)。
  • zset
    格式: zadd name score value
    zset也是string类型元素的集合,不允许重复的成员。每个元素都会关联一个double类型的分数(score,分数可重复),通过分数为集合中的成员进行从小到大的排序。
2、Redis持久化方式及优缺点?

持久化就是把内存的数据写到磁盘中去,防止服务宕机时内存数据丢失。
Redis的持久化方式:RDB(默认) 和AOF。
RDB(Redis DataBase):包含rdbSave(把内存中的数据生成RDB文件)和rdbLoad(把RDB文件加载到内存)两个函数。
AOF(Append-only file):当执行服务器(定时)任务或函数时flushAppendOnlyFile函数都会被调用,函数执行以下两个工作aof写入保存:
WRITE:根据条件将aof_buf中的缓存写入到AOF文件。
SAVE:根据条件调用fsync或fdatasync函数,将AOF文件保存到磁盘。
两种方式对比:
1)aof比rdb更新频率高,优先使用aof还原数据。
2)aof比rdb更大更安全
3)rdb性能更好
4)若两个都配了优先加载aof

3、什么是RESP?有什么特点?

RESP是redis客户端和服务端使用的一种通讯协议;
特点:实现简单、快速解析、可读性好;

4、什么是一致性哈希算法?

一致性哈希将整个哈希值空间组织成一个虚拟的圆环,如假设某哈希函数H的值空间为0-232-1(即哈希值是一个32位无符号整形),整个空间按顺时针方向组织。0和232-1在零点中方向重合。
下一步将各个服务器使用Hash进行一个哈希,具体可以选择服务器的ip或主机名作为关键字进行哈希,这样每台机器就能确定其在哈希环上的位置,这里假设将上文中四台服务器使用ip地址哈希后在环空间的位置如下:

image.png

接下来使用如下算法定位数据访问到相应服务器:将数据key使用相同的函数Hash计算出哈希值,并确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器。例如有Object A、Object B、Object C、Object D四个数据对象,经过哈希计算后,在环空间上的位置如下:
image

根据一致性哈希算法,数据A会被定为到Node A上,B被定为到Node B上,C被定为到Node C上,D被定为到Node D上。
一致性哈希算法的容错性和可扩展性:假设Node C宕机,此时对象A、B、D不会受到影响,只有C对象被重定位到Node D。一般在一致性哈希算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。
如果在系统中增加一台服务器Node X,如下图:
image

此时对象A、B、D不受影响,只有对象C需要重定位到新的Node X 。在一致性哈希算法中,如果增加一台服务器,则受影响的数据仅仅是新服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它数据也不会受到影响。
综上所述:一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。另外,一致性哈希算法在服务节点太少时,容易因为节点分部不均匀而造成数据倾斜问题。例如系统中只有两台服务器,其环分布如下,
image

此时必然造成大量数据集中到Node A上,而只有极少量会定位到Node B上。为了解决这种数据倾斜问题,一致性哈希算法引入了虚拟节点机制,即对每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。具体做法可以在服务器ip或主机名的后面增加编号来实现。如上面的情况,可以为每台服务器计算三个虚拟节点,于是可以分别计算 “Node A#1”、“Node A#2”、“Node A#3”、“Node B#1”、“Node B#2”、“Node B#3”的哈希值,于是形成六个虚拟节点:
image

同时数据定位算法不变,只是多了一步虚拟节点到实际节点的映射,例如定位到“Node A#1”、“Node A#2”、“Node A#3”三个虚拟节点的数据均定位到Node A上。这样就解决了服务节点少时数据倾斜的问题。在实际应用中,通常将虚拟节点数设置为32甚至更大,因此即使很少的服务节点也能做到相对均匀的数据分布。

5、什么是哈希槽?

redis3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。
结构特点:
1)所有redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
2)节点的fail是通过集群中超过半数的节点检测失效时才生效。
3)客户端与redis节点直连,不需要中间proxy层,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
4)redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster负责维护node<->slot<->value。
5)Redis集群预分好16384个桶,当需要在Redis集群中放置一个key-value时,根据CRC16(key) mod 16384的值,决定将一个key放到哪个桶中。

6、Redis有哪些架构模式?
  • 单机版
    特点:简单
    问题:
    1)内存容量有限
    2)处理能力有限
    3)无法高可用
  • 主从复制
    Redis的复制(replication)功能允许用户根据一个Redis服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步 给从服务器,从而一直保证主从服务器的数据相同。
    特点:
    1)master/slave 角色
    2)master/slave 数据相同
    3)降低master读压力,并转交给从库
    问题:
    1)无法保证高可用
    2)无法解决master写压力
  • 哨兵
    Redis sentinel是一个分布式系统中监控redis主从服务器,并在主服务器下线时自动进行故障转移。其中三个特性:
    监控(Monitoring):Sentinel会不断检查主服务器和从服务器是否运作正常。
    提醒(Notification):当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。
    自动故障迁移(Automatic failover):当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作。
    特点:
    1)保证高可用
    2)监控各个节点
    3)自动故障迁移
    缺点:
    1)主从模式,切换需要时间,会丢数据
    2)没有解决master写压力
  • 集群(proxy型)
    Twemproxy是Twitter开源的redis和memcache快速/轻量级代理服务器,它是一个快速的单线程代理程序,支持Memcached ASCII协议和redis协议。
    特点:
    1)支持多种hash算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins
    2)支持失败节点自动删除
    3)后端Sharding分片逻辑对业务透明,业务方的读写方式和操作单个Redis一致
    缺点:
    1)增加了新的proxy,需要维护其高可用。
    2)failover逻辑需要自己实现,其本身不支持故障的自动转移,可扩展性差,进行扩缩容都需要手动干预。
  • 集群(直连型)
    redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。
    特点:
    1)无中心架构(不存在哪个节点影响性能瓶颈),无proxy层。
    2)数据按照slot存储分布在多个节点,节点间数据共享,可动态调整数据分布。
    3)可线性扩展到1000个节点,节点可动态添加或删除。
    4)高可用性,部分节点不可用时,集群仍可用。通过增加Slave做备份数据副本。
    5)实现故障自动failover,节点间通过gossip协议交换状态信息,用投票机制完成Slave到Master的角色提升。
    缺点:
    1)资源隔离性较差,易出现相互影响的情况。
    2)数据通过异步复制,不能保证数据的强一致性。
7、Redis分布式锁是怎么实现的?

先拿setnx来争抢锁,抢到后再用expire给锁加一个过期时间,防止锁忘记释放。
如果在setnx之后执行expire之前进程意外crash或者要重启维护了会怎么样?
set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用。

8、Redis做异步队列是怎么用的?有什么缺点?

一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。
可不可以不用sleep呢?
list还有个指令叫blpop,在没有消息时,它会阻塞直到消息到来。
能不能生产一次消费多次呢?
使用pub/sub主题订阅者模式,可以实现1:N的消息队列,即生产一次消费多次。
pub/sub有什么缺点?
在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如rabbitmq等。
redis如何实现延时队列?
使用sortedset,拿时间戳作为score,消息内容作为key,调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据,轮询进行处理。

9、什么是缓存穿透?如何避免?

缓存穿透:一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力,这就叫缓存穿透。
避免方式:
1)对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert之后清理缓存。
2)对一定不存在的key进行过滤,可以把所有可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。

10、什么是缓存雪崩?何如避免?

缓存雪崩:当缓存服务器重启或大量缓存集中在某个时间段失效,在失效时会给后端系统带来很大压力,导致系统崩溃。
避免方式:
1)在缓存失效后,通过加锁或队列来控制读数据库和写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
2)做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期。
3)不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

11、Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来?

使用keys指令可以扫出指定模式的key列表。
redis是单线程的,keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。此时可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但会有一定的重复概率,在客户端做一次去重就可以了,但整体所花费的时间会比直接用keys指令长。

12、如果有大量的key需要设置同一时间过期,需要注意什么?

如果大量的key过期时间设置的过于集中,到过期的那个时间点,redis可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使过期时间分散一些。

13、Redis如何做持久化的?

bgsave做镜像全量持久化,aof做增量持久化。bgsave会耗费较长时间,在停机时会导致大量数据丢失,需要aof来配合使用。在redis实例重启时,优先使用aof来恢复内存的状态,如果没有aof日志,就会使用rdb文件来恢复。
如果aof文件过大恢复时间过长怎么办?
Redis会定期做aof重写,压缩aof文件日志大小。Redis4.0之后有了混合持久化的功能,将bgsave的全量和aof的增量做了融合处理,既保证了恢复效率又兼顾了数据的安全性。
如果机器突然断电会怎样?
取决于aof日志sync属性的配置,如果不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。在高性能的要求下每次都sync是不现实的,一般使用定时sync,如1s1次,最多会丢失1s的数据。

14、Pipeline有什么好处,为什么要用pipeline?

可以将多次IO往返的时间缩减为一次,前提是pipeline执行的指令之间没有因果相关性。使用redis-benchmark进行压测时可以发现影响redis的QPS峰值的一个重要因素是pipeline批次指令的数目。

15、Redis的同步机制?

从从同步。第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接收完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放,就完成了同步过程。

16、Redis集群的原理?

Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。
Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。

17、Redis有哪几种数据淘汰策略?

noeviction:当内存限制达到返回错误,并且客户端尝试执行会让更多内存被使用的命令。
allkeys-lru:尝试回收最少使用的键(LRU),使新添加的数据有空间存放。
volatile-lru:尝试回收最少使用的键(LRU),仅限于在过期集合的键,使新添加的数据有空间存放。
allkeys-random:回收随机的键使新添加的数据有空间存放。
volatile-random:回收随机的键使新添加的数据有空间存放,仅限于在过期集合的键。
volatile-ttl:回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使新添加的数据有空间存放。

18、为什么Redis需要把所有数据放到内存中?

为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。redis具有快速和数据持久化的特征,若不放在内存中,磁盘I/O速度会严重影响redis的性能。 如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。

19、Redis有哪些适合的场景?

1)会话缓存(Session Cache)
最常用的一种情景是会话缓存(session cache),用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。
2)全页缓存(FPC)
除基本的会话token外,Redis还提供简便的FPC平台。即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。
3)队列
Reids在内存存储引擎领域的一大优点是提供list和set操作,使Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,类似于本地程序语言对list的push/pop操作。
4)排行榜/计数器
Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(SortedSet)使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。
5)发布/订阅
发布/订阅的使用场景非常多。在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统。

20、Redis集群的主从复制模型是怎样的?

为了使在部分节点失败或大部分节点无法通信的情况下集群仍可用,集群使用了主从复制模型,每个节点都会有N-1个复制品。

21、Redis集群会有写操作丢失吗?

Redis并不能保证数据的强一致性,在实际中集群在特定的条件下可能会丢失写操作。

22、Redis集群之间是如何复制的?

异步复制

23、Redis集群最大节点个数是多少?

16384个

24、怎么理解Redis事务?

事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行,事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。事务是一个原子操作:事务中的命令要么全被执行,要么全不执行。

25、Redis事务相关的命令有哪几个?

MULTI、EXEC、DISCARD、WATCH

26、Redis key的过期时间和永久有效怎么设置?

EXPIRE和PERSIST命令

27、Redis如何做内存优化?

尽可能使用散列表(hashes),散列表使用的内存非常小,应该尽可能的将数据模型抽象到一个散列表里。 比如web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而应该把这个用户的所有信息存储到一张散列表里。

28、Redis回收进程如何工作的?

一个客户端运行了新命令,添加了新数据。Redis检查内存使用情况,如果大于maxmemory限制, 则根据设定好的策略进行回收、一个新命令被执行等。 所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。如果一个命令的结果导致大量内存被使用,不用多久内存限制就会被这个内存使用量超越。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • 一、Redis高可用概述 在介绍Redis高可用之前,先说明一下在Redis的语境中高可用的含义。 我们知道,在w...
    空语阅读 1,593评论 0 2
  • 1、什么是Redis   Redis是一个高性能的key/value的分布式内存数据库,基于内存运行并支持持久化的...
    小胖六阅读 377评论 3 0
  • 企业级redis集群架构的特点 海量数据 高并发 高可用 要达到高可用,持久化是不可减少的,持久化主要是做灾难恢复...
    lucode阅读 2,191评论 0 7
  • Redis杂谈 Redis是近年来发展迅速的内存数据库,网上也已经有多Redis的文章。但不管是英文还是中文,多数...
    迷失于重逢阅读 1,523评论 0 14
  • 羡慕十六七岁乃至更小,以为自己是个小大人了,结果一不开心就发个朋友圈,又或者过节乃至天变了都发个朋友圈艾特一大堆人...
    SlothAndSnail阅读 317评论 0 0