Redis 50问

1、什么是Redis?

   Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库。Redis全称为:Remote Dictionary Server(远程数据服务),该软件使用C语言编写,Redis是一个key-value存储系统,它支持丰富的数据类型,如:string、list、set、zset(sorted set)、hash。

2、Redis相比memcached有哪些优势?

(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型

(2) redis的速度比memcached快很多

(3) redis可以持久化其数据


3、Redis支持哪几种数据类型?

  string、list、set、zset(sorted set)、hash

4、Redis主要消耗什么物理资源?

  Redis的数据全部放在内存带来了高速的性能

5、Redis的全称是什么?

  Redis全称为:Remote Dictionary Server(远程数据服务)

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

  1. volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
  4. allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
  6. no-enviction(驱逐):禁止驱逐数据

7、Redis官方为什么不提供Windows版本?

     Redis目前有很多重要并且复杂的工作要做,而对到Win平台的支持显然不在这些事情中。并且按作者的看法,Linux在作为软件部署平台这事      上,已经早就将Win平台撂倒了,对Win的支持是不重要也不紧急的事。

8、一个字符串类型的值能存储最大容量是多少?

   项目中使用redis存储,key-value方式,在Redis中字符串类型的Value最多可以容纳的数据长度是512M 
   官方信息: 
    A String value can be at max 512 Megabytes in length.

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

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

10、Redis集群方案应该怎么做?都有哪些方案?

     https://blog.csdn.net/kingice1014/article/details/53493287

11、Redis集群方案什么情况下会导致整个集群不可用?

12、MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据?

     redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:

  (1)volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

  (2)volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

  (3)volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

  (4)allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

  (5)allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

  (6)no-enviction(驱逐):禁止驱逐数据

   提供一种简单实现缓存失效的思路: LRU(最近少用的淘汰)即redis的缓存每命中一次,就给命中的缓存增加一定ttl(过期时间)(根据具体情况来设定, 比如10分钟).一段时间后, 热数据的ttl都会较大, 不会自动失效, 而冷数据基本上过了设定的ttl就马上失效了.

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

  

  1、会话缓存(Session Cache)

  最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提  供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?

 幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供 Redis的插件。

2、全页缓存(FPC)

除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。

再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端

此外,对WordPress的用户来说,Pantheon有一个非常好的插件  wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

3、队列

Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。

如果你快速的在Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。

排行榜/计数器

Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:

当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:

ZRANGE user_scores 0 10 WITHSCORES

Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。

5、发布/订阅

最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!(不,这是真的,你可以去核实)。

Redis提供的所有特性中,我感觉这个是喜欢的人最少的一个,虽然它为用户提供如果此多功能。

  14、Redis支持的Java客户端都有哪些?官方推荐用哪个?

        Jedis

15、Redis和Redisson有什么关系?

       Redisson - 是一个高级的分布式协调Redis客服端,能帮助用户在分布式环境中轻松实现一些Java的对象 

16、Jedis与Redisson对比有什么优缺点?

17、Redis如何设置密码及验证密码?

18、说说Redis哈希槽的概念?

     Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 取模,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。Redis 集群没有使用一致性hash, 而是引入了哈希槽的概念。Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽。这种结构很容易添加或者删除节点,并且无论是添加删除或者修改某一个节点,都不会造成集群不可用的状态。
     使用哈希槽的好处就在于可以方便的添加或移除节点。当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以了;当需要移除节点时,只需要把移除节点上的哈希槽挪到其他节点就行了;在这一点上,我们以后新增或移除节点的时候不用先停掉所有的 redis 服务。

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

    redis 支持 master-slave(主从)模式,redis server 可以设置为另一个 redis server 的主机(从机),从机定期从主机拿数据。特殊的,一个 从机同样可以设置为一个 redis server 的主机,这样一来 master-slave 的分布看起来就是一个有向无环图 DAG,如此形成 redis server 集群,无论是主机还是从机都是 redis server,都可以提供服务)。

   在配置后,主机可负责读写服务,从机只负责读。redis 提高这种配置方式,为的是让其支持数据的弱一致性,即最终一致性。在业务中,选择强一致性还是若已执行,应该取决于具体的业务需求,像微博,完全可以使用弱一致性模型;像淘宝,可以选用强一致性模型。redis 主从复制的实现主要在 replication.c 中。

20、Redis集群会有写操作丢失吗?为什么?

Redis集群无法提供强一致性,在实际的环境中这意味着在某一情形下,Redis集群有可能丢失掉部分数据,尽管系统已经发送确认给客户端。 丢失数据的第一个原因是主从同步用的是异步模式,在下述场景下就有可能丢失数据:
  • 客户端发送写请求给master B
  • B 返回ok给客户端
  • B 将写的操作传递给Slave B1, B2, B3
在上述场景中,B并没有等待B1, B2, B3的确认就直接返回给客户端OK,这样如果在B将写请求发送给slave的时候挂掉了,而那些没有收到这个写请求的slave节点被提升为Master节点,其他的slave节点再从这个新的master节点同步数据,那这写操作的数据就会永远的丢失掉。
这与大多数数据库配置将数据每秒刷新到磁盘上很类似。所以你就能够明白这个场景,因为传统的数据库系统没有涉及到分布式系统的。你也可以通过强制在数据刷新到磁盘后在返回ok给客户端来改善一致性,但这通常会导致低性能。这等价于Redis Cluster的同步复制功能。
通常我们要在性能和一致性之间进行权衡。Redis Cluster支持同步写,通过WAIT命令,这将会很少丢失数据,但是注意:Redis集群没有实现强一致性,即在这种情况下,还是有可能会丢失数据的,具体场景就就不再列举了,可参考Redis Cluster自己的介绍:Redis Cluser tutorial

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


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

Redis 集群的键空间被分割为 16384 个槽(slot), 集群的最大节点数量也是 16384 个。

23、Redis集群如何选择数据库?

  在集群模式下这个配置是不起作用的,集群客户端是不支持多数据库db的,只有一个数据库默认是SELECT 0;

24、怎么测试Redis的连通性?

Redis Ping 命令使用客户端向 Redis 服务器发送一个 PING ,如果服务器运作正常的话,会返回一个 PONG 。

通常用于测试与服务器的连接是否仍然生效,或者用于测量延迟值。


25、Redis中的管道有什么用?

Redis的管道可以在大量数据需要一次性操作完成的时候,使用Pipeline进行批处理,将一大队的操作合并成一次操作,可以减少链路层的时间消耗,毕竟频繁操作是不好的嘛.

26、怎么理解Redis事务

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

1 multi 标识一个事务的开始
2 exec 执行某事务块内的所有命令
3 watch key… 监视一个或多个key,如果在事务执行之前这些被监视的key被其他命令修改,这该事务则被取消
4 unwatch 取消watch命令对所有key的监视
5 discard 放弃执行事务

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

29、Redis如何做内存优化?

  • Redis存储的所有数据都使用redisObject来封装,包括string、hash、list、set、zset
  • redisObject的字段:
    • type字段:保存对象使用的数据类型,命令type {key}返回值对象的数据类型
    • encoding字段:保存对象使用的内部编码类型,命令object encoding {key}返回值对象的内部编码类型
    • lru字段:记录对象最后一次被访问的时间(用于内存回收),命令object idletime {key}查看键的空闲时间(可配合scan命令批量查找长期空闲的键进行清理)
    • refcount字段:记录对象的引用计数(用于回收),命令object refcount {key}查看键的引用数
    • *ptr字段:存储值对象的数据或指针,如果是整数,则直接存储数据,否则表示指向数据的指针
  • 字符串长度在39字节以内对象,在创建redisObject封装对象时只需分配内存1次,可提高性能;
  • 缩减键、值对象的长度:简化键名,使用高效的序列化工具来序列化值对象,还可使用压缩工具(Google Snappy)压缩序列化后的数据;
  • 共享对象池:Redis内部维护[0-9999]的整数对象池,对于0-9999的内部整数类型的元素、整数值对象都会直接引用整数对象池中的对象,因此尽量使用整数对象可节省内存;
    • 注意:
      • 启用LRU相关的溢出策略时,无法使用共享对象池;
      • 对于ziplist编码的值对象,也无法使用共享对象池(成本过高)

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

  LRU

31、Redis回收使用的是什么算法?

  • volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

  • volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

  • volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

  • allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

  • allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

  • no-enviction(驱逐):禁止驱逐数据


32、Redis如何做大量数据插入?

   Redis作为高性能的Nosql数据库越来越受欢迎,并在使用很多应用场景。常见的一种用法就是缓存一些用户数据。通常我们也  会因为有特殊要求,手动插入一些缓存数据。

  数据量小的时候,可以直接插入。由于redis是单线程的模式,数据量很大的时候也是一个线程处理并发,单条的插入的时间也 会随着数据规模线性增长。同时还会无疑给redis带来类似ddos的操作,虽然redis的性能足够抗住这些并发。

一个行之有效的方式就是使用redis的Redis Mass Insertion – Redis)方式。

pipline模式插入

将需要插入的redis命令按照redis协议进行编码,然后通过管道传给redis-cli,配置—pipe选项即可。

33、为什么要做Redis分区?


34、你知道有哪些Redis分区实现方案?

分区:如何在多个Redis实例中分割数据

分区是分割数据到多个Redis实例的处理过程,因此每个实例只保存key的一个子集。文档的第一部分会介绍分区的概念,第二部分会展示Redis分区的可选方案。

为什么分区有用

Redis分区有两个主要目的:

  • 可以支持更大的数据库,使用很多计算机的所有内存。没有分区,就被限制在单台计算机所能支持的最大内存。

  • 可以扩展多核和多个计算机的计算能力,还有多个计算机和网络适配器的网络带宽。

分区基础

有不同的分区标准。假设有4个Redis实例 R0,R1,R2,R3,和类似user:1,user:2这样的表示用户的多个key,对既定的key有多种不同方式来选择这个key存放在哪个实例中。也就是说,有不同的系统来映射某个key到某个Redis服务。

最 简单的分区方式是按范围分区,就是映射一定范围的对象到特定的Redis实例。比如,ID从0到10000的用户会保存到实例R0,ID从10001到 20000的用户会保存到R1,以此类推。这种方式是可行的,并且在实际中使用,不足就是要有一个区间范围到实例的映射表。这个表要被管理,同时还需要各 种对象的映射表,通常对Redis来说并非是好的方法。

另外一种分区方法是hash分区。这对任何key都适用,也无需是object_name:<id>这种形式,像下面描述的一样简单:

  • 用一个hash函数将key转换为一个数字,比如使用crc32 hash函数。对key foobar执行crc32(foobar)会输出类似93024922的整数。

  • 对这个整数取模,将其转化为0-3之间的数字,就可以将这个整数映射到4个Redis实例中的一个了。93024922 % 4 = 2,就是说key foobar应该被存到R2实例中。注意:取模操作是取除的余数,通常在多种编程语言中用%操作符实现。

有很多实现分区的其他方法,基于这两个例子,你应该有了认识。hash分区的一种更高级形式叫一致性hash,有些Redis客户端和代理已经实现。

分区的不同实现

分区可以是软件系统中不同部分来实现。

  • 客户端分区 意味着客户端直接选择对应的节点,被给定key读取或写入。很多Redis客户端实现了客户端分区。

  • 代理辅助分区 意味着客户端发送请求给实现Redis协议的代理,而非直接发送请求给对应的Redist实现。代理会参照配置好的分区策略,保证转发请求给正确的Redis实例,也会给客户端返回响应。Redis和Memcached代理Twemproxy实现了代理辅助分区。

  • 查询路由 意味着发送请求给一个随机的实例,这个实例会保证转发请求到正确的节点。在客户端的帮助下,Redis集群实现了一种混合形式的查询路由(请求不是直接从一个Redis实例转发到另一个实例,而由客户端重定向到正确的节点)。

分区不足之处

Redis的某些特性在分区环境下不能充分发挥:

  • 多key操作通常无法支持。比如,如果两个key被映射到不同的Redis实例,无法对两个set取交集(实际有方法实现,但不能非直接实现)。

  • 多key的事务无法使用。

  • 分区粒度是关键,因此,不可能对一个key下面有非常多元素的sorted set分片。

  • 使用分区时,数据处理更复杂。不得不处理多个RDB/AOF文件,做数据备份时需要合并来自多个实例和机器的持久文件。

  • 添加或删除容量可能会复杂。比如,Redis集群计划支持透明重新平衡数据的能力,以支持运行时添加和删除节点,但是其他采用客户端分区和代理的系统就不支持这个特性。但是,Presharding预分片技术在这方面会有帮助。

数据存储还是Cache?

使 用Redis做为存储或cache,分区在概念上是相同的, 但是有一个巨大的差别。Redis做为数据存储时,要保证给定key总是映射到相同的实例,而Redis做为cache时,一个给定节点不可用,如果开始 使用一个不同的node,不会有太大问题,只要我们愿意,更新key和实例的映射以提升系统可用性(即,对查询响应的系统能力)。

如果给定key的首选节点不可用,一致性hash实现常可以切换到其他节点。类似的,如果添加一个新节点,部分新key开始存到新节点上。

以下是主要概念:

  • 如果Redis用作cache,使用一致性hash容易向上向下扩展。

  • 如果Redis用作存储,要在key和固定节点之间做映射,并且有固定数量的节点。否则在增加或删除节点时,就需要一个系统节点之间对key做迁移。当前,只有Redis集群可以实现,但是在生产环境还不能用。

预分片

我们了解到,分区是个问题,除非我们使用Redis做为cache,添加删除节点可能会困难,使用固定的key和实例映射会简单的多。

数据存储需求随着时间变化,今天我可能使用10个Redis节点,明天可能就需要50个节点。

Redis非常小和轻量(一个备用实例仅适用1mb内存容),解决分片问题的一个简单方法是一开始就启动多个实例。即使你只启动一个服务器,第一天就使用分布式,单台服务器上运行多个Redis实例,来使用分区。

从一开始你可以将实例数开的很大,比如32或64个实例,对大多数用户足够满足增长需要。

随着你的存储需求增长,需要更多的Redis服务器,使用这种方式,要做的就是简单的将实例从一台服务器移到另一台。一旦添加了第一个额外的服务器,需要将一半的Redis实例从第一台服务器移到第二台,以此类推。

使用Redis复制你可能会最小代价迁移,对用户无需停机:

  • 在你的新服务器上启动空实例

  • 迁移数据配置这些新实例做为源实例的备机

  • 停止客户端

  • 使用新的服务器IP更新迁移实例的配置

  • 发送SLAVEOF NO ONE命令到新服务器上的备机

  • 用新更新的配置重启客户端

  • 最后关闭老服务器上不再使用的实例

Redis分区实现

到现在,理论上覆盖了Redis分区,但是实际中怎么样?你会使用什么方案?

Redis集群

不幸的是,Redis集群现在还不能在生产环境使用,但是可以阅读规范或了解现在不稳定分支的部分实现,以获得更多相关信息。

一旦Redis集群可用,并且Redis集群兼容客户端在你所用编程语言中可用,Redis集群会成为事实上的Redis分区标准。

Redis集群是一种查询录用和客户端分区的混合解决方案。

Twemproxy

Twemproxy 是Twitter为Memchache ASCII和Redis协议开发的一个代理。单线程,C语言开发,非常快。基于Apache 2.0 license的开源软件。

Twemproxy支持自动在多个Redis实例间自动分区,节点不可用时可以屏蔽(这会改变key和实例映射关系,应该在将Redis做为cache使用时才用这项特性)。

没有单点故障,因为你可以启动多个代理引导客户端连接首先接受连接的那个。

基本上,Twemproxy是一个介于客户端和Redis实例之间的中间层,用最小的额外复杂度来可靠的分区。目前是处理Redis分区的推荐方式。

可以通过这篇blog了解更多关于Twemproxy的信息。

支持一致性hash的客户端

Twemproxy的可选方案是,使用使用一致性 hash或类似算法的客户端分区。有多个Redis客户端都支持一致性hash,特别是Redis-rb和Predis。

查看完整的Redis客户端列表,以检查是否有你使用的编程语言的实现一致性hash的合适客户端。


35、Redis分区有什么缺点?

Redis分区缺点:

Redis分区在有些方面做的并不好:

  • 不支持多个键的操作。比如你不能操作映射在两个Redis实例上的两个集合的交叉集。(其实可以做到这一点,但是需要间接的解决).
  • Redis不支持多个键的事务。
  • Redis是以键来分区,因此不能使用单个大键对数据集进行分片,例如一个非常大的有序集。
  • 如果使用分区,数据的处理会变得复杂,比如你必须处理多个RDB和AOF文件,在多个实例和主机之间持久化你的数据。
  • 添加和删除节点也会变得复杂。例如通过在运行时添加和删除节点,Redis集群通常支持透明地再均衡数据,但是其他系统像客户端分区或者代理分区的特性就不支持该特性。不过Pre-sharding(预分片)可以在这方面提供帮助。

36、Redis持久化数据和缓存怎么做扩容?

如果Redis被当做缓存使用,使用一致性哈希实现动态扩容缩容。

如果Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定不能变化。否则的话(即Redis节点需要动态变化的情况),必须使用可以在运行时进行数据再平衡的一套系统,而当前只有Redis集群可以做到这样。


37、分布式Redis是前期做还是后期规模上来了再做好?为什么?

既然Redis是如此的轻量(单实例只使用1M内存),为防止以后的扩容,最好的办法就是一开始就启动较多实例。即便你只有一台服务器,你也可以一开始就让Redis以分布式的方式运行,使用分区,在同一台服务器上启动多个实例。

一开始就多设置几个Redis实例,例如32或者64个实例,对大多数用户来说这操作起来可能比较麻烦,但是从长久来看做这点牺牲是值得的。

这样的话,当你的数据不断增长,需要更多的Redis服务器时,你需要做的就是仅仅将Redis实例从一台服务迁移到另外一台服务器而已(而不用考虑重新分区的问题)。一旦你添加了另一台服务器,你需要将你一半的Redis实例从第一台机器迁移到第二台机器。


38、Twemproxy是什么?

Twemproxy是Twitter维护的(缓存)代理系统,代理Memcached的ASCII协议和Redis协议。它是单线程程序,使用c语言编写,运行起来非常快。它是采用Apache 2.0 license的开源软件。 Twemproxy支持自动分区,如果其代理的其中一个Redis节点不可用时,会自动将该节点排除(这将改变原来的keys-instances的映射关系,所以你应该仅在把Redis当缓存时使用Twemproxy)。 Twemproxy本身不存在单点问题,因为你可以启动多个Twemproxy实例,然后让你的客户端去连接任意一个Twemproxy实例。 Twemproxy是Redis客户端和服务器端的一个中间层,由它来处理分区功能应该不算复杂,并且应该算比较可靠的。

39、支持一致性哈希的客户端有哪些?

Redis-rb、Predis等。

40、Redis与其他key-value存储有什么不同?

Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。

Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,应为数据量不能大于硬件内存。在内存数据库方面的另一个优点是, 相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。 同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。


41、Redis的内存占用情况怎么样?

给你举个例子: 100万个键值对(键是0到999999值是字符串“hello world”)在我的32位的Mac笔记本上 用了100MB。同样的数据放到一个key里只需要16MB, 这是因为键值有一个很大的开销。 在Memcached上执行也是类似的结果,但是相对Redis的开销要小一点点,因为Redis会记录类型信息引用计数等等。

当然,大键值对时两者的比例要好很多。

64位的系统比32位的需要更多的内存开销,尤其是键值对都较小时,这是因为64位的系统里指针占用了8个字节。 但是,当然,64位系统支持更大的内存,所以为了运行大型的Redis服务器或多或少的需要使用64位的系统。

42、都有哪些办法可以降低Redis的内存使用情况呢?

如果你使用的是32位的Redis实例,可以好好利用Hash,list,sorted set,set等集合类型数据,因为通常情况下很多小的Key-Value可以用更紧凑的方式存放到一起。

43、查看Redis使用情况及状态信息用什么命令?

 info

44、Redis的内存用完了会发生什么?

如果达到设置的上限,Redis的写命令会返回错误信息(但是读命令还可以正常返回。)或者你可以将Redis当缓存来使用配置淘汰机制,当Redis达到内存上限时会冲刷掉旧的内容。

45、Redis是单线程的,如何提高多核CPU的利用率?

可以在同一个服务器部署多个Redis的实例,并把他们当作不同的服务器来使用,在某些时候,无论如何一个服务器是不够的, 所以,如果你想使用多个CPU,你可以考虑一下分片(shard)。

46、一个Redis实例最多能存放多少的keys?List、Set、Sorted Set他们最多能存放多少元素?

Redis can handle up to 232 keys, and was tested in practice to handle at least 250 million of keys per instance.

Every hash, list, set, and sorted set, can hold 232 elements.

In other words your limit is likely the available memory in your system


47、Redis常见性能问题和解决方案?

(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件 

(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次

(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

(4) 尽量避免在压力很大的主库上增加从库

(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...

这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。


48、Redis提供了哪几种持久化方式?

RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储.

AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.

如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.

你也可以同时开启两种持久化方式, 在这种情况下, 当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.

最重要的事情是了解RDB和AOF持久化方式的不同,让我们以RDB持久化方式开始


49、如何选择合适的持久化方式?

一般来说, 如果想达到足以媲美PostgreSQL的数据安全性, 你应该同时使用两种持久化功能。如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失,那么你可以只使用RDB持久化。

有很多用户都只使用AOF持久化,但并不推荐这种方式:因为定时生成RDB快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比AOF恢复的速度要快,除此之外, 使用RDB还可以避免之前提到的AOF程序的bug

50、修改配置不重启Redis会实时生效吗?

针对运行实例,有许多配置选项可以通过 CONFIG SET 命令进行修改,而无需执行任何形式的重启。 从 Redis 2.2 开始,可以从 AOF 切换到 RDB 的快照持久性或其他方式而不需要重启 Redis。检索 ‘CONFIG GET *’ 命令获取更多信息。

但偶尔重新启动是必须的,如为升级 Redis 程序到新的版本,或者当你需要修改某些目前 CONFIG 命令还不支持的配置参数的时候。

51 数据分区的方法

 通常有三种方法来对数据进行分区,客户端分区,辅助代理分区以及查询路由。查询路由是redis集群的实现方式。

 范围分区:将一组范围分区的redis键映射到特定的实例,典型采用name:id的形式

列表分区:如果redis键拥有列表值中的一个,那么就将该键分配到那个分区

哈希分区:计算分区的哈希值

复合分区:在复合分区策略中,键会用过范围分区,列表分区或者哈希分区之间不同组合的分区计算方式。redis集群使用一种一致性哈希的复合分区方式,这种分区方式组合了哈希分区和列表分区的特征来计算键的归属实例。键的CRC16哈希值被称为哈希槽,然后使用16384进行取模或者CRC16(循环冗余校验)模运算。

一个键真正对应的哈希槽是通过计算键的CRC16哈希值,然后对16384进行取模得到的。

强制键能够驻留到集群中同一个节点的方法:键哈希标签。创建{book}哈希标签并发送两个


猜你喜欢

转载自blog.csdn.net/qiuyumin430/article/details/80035184
今日推荐