目录

Redis面试

Redis有几种持久化方式

  1. 一种叫快照snapshot,它可以将存在于某一时刻的所有数据写入硬盘里面
  2. 一种叫只追加文件AOF append-only file,它会执行写命令的时候,将被执行的写命令复制到硬盘里

快照的用途是什么

  1. 创建快照之后可以进行备份,可以把快照复制到其他服务器从而创建具有相同数据的服务器副本
  2. 还可以把快照留在原地以便重启服务器的时候使用。但是快照持久化只适用于那些即使丢失一部分数据也不会造成问题的应用程序。

查看配置

1
2
3
4
5
6
7
# 查看某个配置
10.25.135.6:6379> config get dir
1) "dir"
2) "/var/lib/redis/6379"

# 查看所有配置
10.25.135.6:6379> config get *

比较一下快照和AOF方式丢失数据的时间范围

AOF 如果开启 everysec,性能不会造成太大影响,此外即使丢失数据也就是一秒的数据而已,如果开成每条数据做持久化,那可能对性能影响会比较大了。

使用Redis需要提前规划一些灾难场景

比如丢失数据,比如硬盘失效,如何快速容灾。

说说Redis Sentinel的作用

可以配合 Redis 的复制功能使用,并对下线的主服务器进行故障转移,Redis Sentinel 是运行在特殊模式下的 Redis 服务器,但它的行为和一般的 Redis 服务器不相同,他会监视一系列主服务器以及这些主服务器的从服务器,通过向主服务器发送 PUBLISH 和 SUBSCRIBE 命令,并向主服务器发送 PING 命令,各个 Sentinel 进程可以自主识别可用的从服务器和其他的 Sentinel。

Redis的分片预分片技术总结

https://blog.csdn.net/houjixin/article/details/38304081

Redis 的分片 Sharding 或者 Partitioning 技术是指将数据分散到多个 Redis 实例中的方法,分片之后,每个 Redis 拥有一部分原数据集的子集。在数据量非常大时,这种技术能够将数据量分散到若干主机的 Redis 实例上,进而减轻单台 Redis 实例的压力。分片技术能够以更易扩展的方式使用多台计算机的存储能力(这里主要指内存的存储能力)和计算能力。

  1. 从存储能力的角度,分片技术通过使用多台计算机的内存来承担更大量的数据,如果没有分片技术,那么 Redis 的存储能力将受限于单台主机的内存大小。
  2. 从计算能力的角度,分片技术通过将计算任务分散到多核或者多台主机中,能够充分利用多核、多台主机的计算能力。

下面将以举例的方式说明分片技术及其存在的优势:

示例1: 未采用分片技术,有1000万条用户信息数据,以键值对 UsrID:UsrInfo 的形式存储在一个 Redis 实例中,此时所有的用户信息都会存储在一个 Redis 实例中,对这1000万条数据的所有插、查、删、该操作压力都会集中在这个 Redis 所在的主机上;此时所要考虑的问题不仅有存储和操作对该主机的压力,还有该主机失效时将导致所有操作都无法进行的问题。如下图1所示。

/redis%E9%9D%A2%E8%AF%95/img1.png

示例2: 采用分片技术。有1000万条用户信息数据,以键值对 UsrID:UsrInfo 的形式存储于 Redis 中,此时有4台主机,每台主机运行一个 Redis 实例:主机A (Redis1)、主机B(Redis2)、主机C(Redis3)、主机D(Redis4),分片时算法为:

1
redis_index = 用户的ID % 4 + 1

例如ID为10000654则可得到到 redis_index 的值:10000654 % 4 + 1 = 1,即用户10000654的信息将被放到 Redis1 上,所有对用户1000654的操作也将被分片到 Redis1 上。假如用户ID以顺序方式出现,这1000万条用户信息将被平均分配到这四台主机的各 Redis 实例上,如下图2所示:

/redis%E9%9D%A2%E8%AF%95/img.png

采用分片之后,数据将被分散到4个 Redis 实例中,对数据的操作也被分散到每个 Redis 实例中,此时单台主机的压力将大大减轻。

分片的部署,即实例2中分片算法被放在哪里?是在分片时需要首先考虑的问题,分片部署方式一般分为以下三种:

  1. 在客户端做分片: 这种方式在客户端确定要连接的Redis实例,然后直接访问相应的Redis实例
  2. 在代理中做分片: 这种方式中,客户端并不直接访问Redis实例,它也不知道自己要访问的具体是哪个Redis实例,而是由代理转发请求和结果;其工作过程为,客户端先将请求发送给代理,代理通过分片算法确定要访问的是哪个Redis实例,然后将请求发送给相应的Redis实例,Redis实例将结果返回给代理,代理最后将结果返回给客户端
  3. 在Redis服务器端做分片: 这种方式被称为查询路由,在这种方式中客户端随机选择一个Redis实例发送请求,如果所请求的内容不再当前Redis实例中它会负责将请求转交给正确的Redis实例,也有的实现中,Redis实例不会转发请求,而是将正确Redis的信息发给客户端,由客户端再去向正确的Redis实例发送请求

分片技术的问题有哪些

上面主要描述了分片的优点,当然分片的存在也有缺陷,例如:

  1. 通常无法支持涉及多键的操作。在Redis中有很多一次操作多个key的操作,例如求集合交集的SINTER操作,该操作将涉及到多个键,而这多个键有可能被分片到不同的Redis实例中,此时就无法执行这种操作
  2. Redis的事务操作中涉及多个键时也不能用
  3. 分片将导致数据处理更加复杂。例如在分片过程中,随着Redis实例的增加,数据备份等操作都将会变得更加复杂
  4. Redis目前不支持动态分片操作,扩容和缩容操作都会比较复杂,尤其分片操作部署在客户端时,需要重新配置和启动客户端。在使用过程中缩容用的不多,扩容可以采用后面介绍的预分片策略来缓解此问题

解释一下预分片技术

在正常运营环境中,一般所存储的数据会逐渐增加,可能今天只要10个 Redis 实例就能应付,但是到了一年以后就需要50个 Redis 实例才能支撑,因此,Redis 的扩容是经常用到的功能,在 Redis 的分布式部署中,有预分片技术是非常好用的方法之一。

预分片技术是指在开始时就启动足够多的Redis实例(例如32或64个,估计一下够以后扩展用就行了),等到后续需要扩容的时候,只需要将其中一部分的 Redis 实例转移到新增加的机子上即可,在 Redis 实例迁移过程中使用 Redis 的复制功能可以最大限度的降低 Redis 的停工时间甚至可以做到没有停工时间。由于 Redis 实例是轻量级的进程,而且占用内存较少,这里指单纯的空的 Redis 实例,一个空的 Redis 实例大约占用1M的内存。因此,这种方式即不会占用太多系统开销,又便于实现。

Redis 的预分片技术可以按照以下步骤进行实例迁移操作:

  1. 在新机子上启动新的Redis实例
  2. 将新Redis实例作为slave将原Redis实例作为master,将数据从原Redis实例迁移到新Redis实例上
  3. 停止客户端(分片操作在客户端上时)或代理服务器(分片操作在代理上)
  4. 更新客户端或者代理服务器中的配置信息,去掉被迁移的原Redis实例的ip和端口等信息,加上新启动Redis实例的IP地址和端口
  5. 向新启动的Redis发送SLAVEOF NOONE命令,终止新Redis实例对原Redis实例的从属关系
  6. 重启客户端程序或者代理程序,此时它们将会使用新的Redis实例
  7. 关掉被迁移走数据的原Redis实例

容量规划的问题

  1. Redis以Hash结构存储数据的时候,key应该尽可能短小,主要为了节省空间。原因在于key减小了,可以让大部分数据结构以ziplist方式压缩存储,而不是HashTable,坏处是增加了一点CPU的性能开销,可以忽略不计
  2. 那些不活跃用户是否可以通过规则来进入缓存,对于不活跃的用户,应该需要过滤一下,比如说一年未有行为的用户,就不应该写入Redis了
  3. 如何取也是关键,不需要的字段field就可以不取了

数一数Redis的数据结构

5种,String, Hash, Set, SortSet, List

一句话Redis

Redis 是一个速度非常快的非关系数据库,可以存储键和5种不同类型的值之间的映射,可以将存储在内存的键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,可以使用客户端分片来扩展写性能。

简单解释一下为什么Redis比关系型数据库快

  1. 内存数据库
  2. 对表更新的时候,除了会引起一次随机读还有一次随机写,而 Redis不需要经过典型的查询分析器或者查询优化器处理,并且数据都在内存里,因此执行随机写的速度总是迅速的
  3. 避免写入不必要的临时数据,也免去了数据进行扫描护着删除的麻烦
警告
本文最后更新于 2017年2月1日,文中内容可能已过时,请谨慎参考。