1、Redis支持哪几种数据类型?
String、List、Set、Sorted Set、hashes
2、Redis主要消耗什么物理资源?
Redis是一种基于内存高性能的数据库--- 主要依赖于内存
3、Redis有哪几种数据淘汰策略?
noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)
allkeys-lru:尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
volatile-lru:尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
allkeys-random:回收随机的键使得新添加的数据有空间存放。
volatile-random:回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
volatile-tt:回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。
4、为什么Redis需要把所有数据放到内存中?
Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度为严重影响redis的性能。在内存越来越便宜的今天,redis将会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
5、Redis集群方案应该怎么做?都有哪些方案?
1.twemproxy,大概概念是,它类似于一个代理方式,使用方法和普通redis无任何区别,设置好它下属的多个redis实例后,使用时在本需要连接redis的地方改为连接twemproxy,它会以一个代理的身份接收请求并使用一致性hash算法,将请求转接到具体redis,将结果再返回twemproxy。使用方式简便(相对redis只需修改连接端口),对旧项目扩展的首选。问题:twemproxy自身单端口实例的压力,使用一致性hash后,对redis节点数量改变时候的计算值的改变,数据无法自动移动到新的节点。
2.codis,目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在 节点数量改变情况下,旧节点数据可恢复到新hash节点。
3.redis cluster3.0自带的集群,特点在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点。具体看官方文档介绍。
4.在业务代码层实现,起几个毫无关联的redis实例,在代码层,对key 进行hash计算,然后去对应的redis实例操作数据。这种方式对hash层代码要求比较高,考虑部分包括,节点失效后的替代算法方案,数据震荡后的自动脚本恢复,实例的监控,等等。
6、Redis集群方案什么情况下会导致整个集群不可用?
有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用。
7、Redis如何设置密码及验证密码?
设置密码:config set requirepass 123456
授权密码:auth 123456
8、说说Redis哈希槽的概念?
Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。
9、Redis集群的主从复制模型是怎样的?
为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品.
10、Redis集群会有写操作丢失吗?为什么?
Redis并不能保证数据的强一致性,这意味着在实际中集群在特定的条件下可能会丢失写操作。
11、Redis集群之间是如何复制的?
异步复制
12、怎么理解Redis事务?
事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
13、Redis事务相关的命令有哪几个?
MULTI、EXEC、DISCARD、WATCH
14、Redis key的过期时间和永久有效分别怎么设置?
EXPIRE和PERSIST命令。
15、Redis如何做内存优化?
尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面.
16、Redis回收进程如何工作的?
一个客户端运行了新的命令,添加了新的数据。
Redi检查内存使用情况,如果大于maxmemory的限制, 则根据设定好的策略进行回收。
一个新的命令被执行,等等。
所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。
如果一个命令的结果导致大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越。
17、Redis回收使用的是什么算法?
LRU算法
18、Redis如何做大量数据插入?
Redis2.6开始redis-cli支持一种新的被称之为pipe mode的新模式用于执行大量数据插入工作。
19、为什么要做Redis分区?
分区可以让Redis管理更大的内存,Redis将可以使用所有机器的内存。如果没有分区,你最多只能使用一台机器的内存。分区使Redis的计算能力通过简单地增加计算机得到成倍提升,Redis的网络带宽也会随着计算机和网卡的增加而成倍增长。
20、Redis持久化数据和缓存怎么做扩容?
如果Redis被当做缓存使用,使用一致性哈希实现动态扩容缩容。
如果Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定不能变化。否则的话(即Redis节点需要动态变化的情况),必须使用可以在运行时进行数据再平衡的一套系统,而当前只有Redis集群可以做到这样。
21、分布式Redis是前期做还是后期规模上来了再做好?为什么?
既然Redis是如此的轻量(单实例只使用1M内存),为防止以后的扩容,最好的办法就是一开始就启动较多实例。即便你只有一台服务器,你也可以一开始就让Redis以分布式的方式运行,使用分区,在同一台服务器上启动多个实例。
一开始就多设置几个Redis实例,例如32或者64个实例,对大多数用户来说这操作起来可能比较麻烦,但是从长久来看做这点牺牲是值得的。
这样的话,当你的数据不断增长,需要更多的Redis服务器时,你需要做的就是仅仅将Redis实例从一台服务迁移到另外一台服务器而已(而不用考虑重新分区的问题)。一旦你添加了另一台服务器,你需要将你一半的Redis实例从第一台机器迁移到第二台机器。
22、都有哪些办法可以降低Redis的内存使用情况呢?
如果你使用的是32位的Redis实例,可以好好利用Hash,list,sorted set,set等集合类型数据,因为通常情况下很多小的Key-Value可以用更紧凑的方式存放到一起。
23、查看Redis使用情况及状态信息用什么命令?
info
24、Redis的内存用完了会发生什么?
如果达到设置的上限,Redis的写命令会返回错误信息(但是读命令还可以正常返回。)或者你可以将Redis当缓存来使用配置淘汰机制,当Redis达到内存上限时会冲刷掉旧的内容。
25、Redis是单线程的,如何提高多核CPU的利用率?
可以在同一个服务器部署多个Redis的实例,并把他们当作不同的服务器来使用,在某些时候,无论如何一个服务器是不够的, 所以,如果你想使用多个CPU,你可以考虑一下分片(shard)。
26、一个Redis实例最多能存放多少的keys?List、Set、Sorted Set他们最多能存放多少元素?
理论上Redis可以处理多达232的keys,并且在实际中进行了测试,每个实例至少存放了2亿5千万的keys。我们正在测试一些较大的值。
任何list、set、和sorted set都可以放232个元素。
换句话说,Redis的存储极限是系统中的可用内存值。
27、Redis常见性能问题和解决方案?
(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
(4) 尽量避免在压力很大的主库上增加从库
(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...
这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。
28、Redis提供了哪几种持久化方式?
RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。
AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾。Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式。
你也可以同时开启两种持久化方式,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
最重要的事情是了解RDB和AOF持久化方式的不同,让我们以RDB持久化方式开始。
29、如何选择合适的持久化方式?
一般来说, 如果想达到足以媲美PostgreSQL的数据安全性, 你应该同时使用两种持久化功能。如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失,那么你可以只使用RDB持久化。
有很多用户都只使用AOF持久化,但并不推荐这种方式:因为定时生成RDB快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比AOF恢复的速度要快,除此之外, 使用RDB还可以避免之前提到的AOF程序的bug。
30、修改配置不重启Redis会实时生效吗?
针对运行实例,有许多配置选项可以通过 CONFIG SET 命令进行修改,而无需执行任何形式的重启。从 Redis 2.2 开始,可以从 AOF 切换到 RDB 的快照持久性或其他方式而不需要重启 Redis。检索 ‘CONFIG GET *’ 命令获取更多信息。
但偶尔重新启动是必须的,如为升级 Redis 程序到新的版本,或者当你需要修改某些目前 CONFIG 命令还不支持的配置参数的时候。
(以上内容来自“Java核心技术”,作者:不羁码农 )
10个 Redis 架构和运维必懂的知识
(以下内容来自社区交流整理,有些问题可能有多个解读)
一、高可用相关
1、Redis 常用高可用架构有哪些?
Redis 高可用架构如下:
—Redis Sentinel 集群 + 内网 DNS + 自定义脚本
优点:
缺点:
—Redis Sentinel 集群 + VIP + 自定义脚本
优点:
缺点:
—封装客户端直连 Redis Sentinel 端口
优点:
缺点:
—Redis Sentinel 集群 + Keepalived/Haproxy
优点:
缺点:
—Redis M/S +Keepalived
优点:
缺点:
(Redis Cluster、Twemproxy、Codis 优劣对比见下个问题)
Twemproxy:
多个同构 Twemproxy(配置相同)同时工作,接受客户端的请求,根据 hash 算法,转发给对应的 Redis。
优点:
缺点:
优点:
缺点:
Redis Cluster:
P2P模式,无中心化。把 key 分成 16384 个 slot,每个实例负责一部分 slot。客户端请求若不在连接的实例,该实例会转发给对应的实例。通过Gossip协议同步节点信息。
优点:
缺点:
二、Redis 通用
1、Redis 相对 MySQL、PostgreSQL 这些关系型数据库,有什么优缺点?
观点一:
Redis 主要是用来做缓存,它有持久化,但也只是为了缓存的可靠而已。优点是数据全放内存,速度快。缺点就是,数据大小不能超过内存大小。两个用在不同业务场景,Redis 无法取代传统关系型数据库。
观点二:
Redis 首先它是一种内存数据库,最大的优势在于效率高。尤其在某些特定场合下,例如热点数据量非常大,而数据从内存和磁盘之间的换入换出代价比较高的情况下,Redis 就会体现它的价值。
传统关系型数据库在于它对数据的一致性保障,它的数据模型范式是遵循严格事务规则的结构化数据,由于其数据的高度抽象化,它调度到内存的数据一般场合下不会占用很大的内存空间。
总的来说,两种数据库各有各的优点和缺点。不同的业务场合有特定的追求目标,redis 首要的是效率,适用的是一些单纯二维结构化数据无法表达的数据模型,而关系型数据库处理的是可以用范式模型表达的二维数据,追求的是数据的高度一致性。随着 IT 的发展,每一类型的数据库都会在其特定的场合内发挥出无可比拟的优势,最终的趋势是大家趋于平衡,没有最好,只有最适合。
观点三:
记住一句话:任何数据库都有自己的应用场景,应该关注数据流、数据属性。
个人的经验来说,Redis 不可能取代 MySQL 或者 PG。
Redis 是一个高性能的缓存,一般应用在 Session 缓存、队列、排行榜、计数器、最近最热文章、最近最热评论、发布订阅等。
更多应用场景,可以参考此处。
可以这样讲,Redis 适用于 数据实时性要求高、数据存储有过期和淘汰特征的、不需要持久化或者只需要保证弱一致性、逻辑简单的场景。
刚刚接手一套 Redis 集群,想要了解这套集群的相关配置。应该如何入手。难道只能通过 info 命令去查看各个配置吗?
这是笔者的建议:
三、Redis 故障排查
1、Redis 实例中,存在大量的 FIN_WAIT2 连接
客户端 TCP 状态迁移:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
服务器 TCP 状态迁移:
CLOSED->LISTEN->SYN 收到 ->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
这个状态存在于主动发起断开请求的一端,如果服务器存在大量的这个状态,那么这个服务器就充当客户端的角色,如网络爬虫,出现的原因是由于客户端发起 FIN 请求结束连接之后,收到了服务端的应答之后进入 FIN_WAIT2,之后就没收到服务端发送的 FIN 信号导致。
PS:线上 Web 客户端用的什么语言?
解答一:
随便 get 一个 key,然后卡着不动就行,简单粗暴。优雅一点是看 latency 的延迟,blocked_clients 的数量,rejected_connections 的数量等。
解答二:
回答一:
常见的运维故障
回答二:
我简单说下 Redis 故障的排查方法吧。
更多的排查需要对线上系统的分析。
四、Redis 性能优化
这个问题有点偏题了,还是回答下吧。整理下工作中积累的经验:
(以上内容由温国兵、liucj2004、赵海等社区专家和会员分享,温国兵整理汇编。)
Redis 调优、监控知识和10个具体应用难点
一、Redis数据库的优缺点及适用场景
Redis持久服务的特点,key-value键值类型存储系统,支持数据可靠存储,单进程单线程高性能服务器,恢复比较慢单机qps(秒并发)可以达到10W,适合小数据高速读写访问。
Redis存储系统优、缺点:可以持久化存储数据,支持每秒10W的读写频率,支持丰富的数据类型,所有操作都是原子性的,支持异机主从复制,内存管理开销大(低于物理内存的3/5),不同命令延迟差别大,官方网站:http://www.redis.io
主要使用场景分为两大块:
1、缓存:热点数据放到缓存里,大部分情况命中缓存,不命中时,访问磁盘存储并更新缓存
2、键值存储,独立使用缓存作为数据提供方。依赖于缓存服务的可靠性不高,业务对事务和数据的一致性要求不高。具体的,一般由架构师和开发人员,根据业务的特性,设计出具体的使用方法。
Redis的参数调优问题,根据场景不同,有不同的调优方法,以下列举踩过的一些坑的参数调优。我们的场景的海量数据,高并发。
(1)timeout参数,非常需要关注,官方对timeout的解释如下:该参数表示当某一个客户端连接上来并闲置timeout(单位秒)的时间后,Redis服务端就主动关闭这个客户端连接。我们发现如果客户端对连接处理比较差的时候,存在连接不释放的问题,导致连接池耗尽,单个redis默认的连接数是1000.所以需要在timeout参数做文章,强制释放无效连接,我们的参数调整为timeout 30000
(2)持久化参数,RDB和AOF究竟开哪个,很多人很纠结。其实选择很简单,两者的区别是持久化的颗粒度不一样,如果你关注数据的强一致性,选择AOF,如果你选择更好的性能,选型RDB。如果你选择极致的性能,又能容忍数据的丢失,那你可以完全不用开启持久化,当然了,集群是一定要开持久化的。
(3)tcp-backlog和maxclient,这两个参数可能大家也比较迷糊,maxclient模式10000,一般情况下是够了,但是在高并发海量访问的时候,还是会出现客户端缓慢的情况,那就是系统的限制,就是backlog参数,你可以理解为在三次握手时进入accept queue队列的最大值,也就是send_Q,所以这个值设大点是没有坏处的,我们的设置是1024
(4)重点提一下安全的参数,requirepass foobared 个人认为,如果你们觉得你们hold住,那就不用开,如果在DMZ区,数据又比较重要,那就开。个人认为,密码的作用不是你想象中的带给你安全,第一redis一分钟可以访问你想象不到的次数,如果弱密码,分分钟破解,第二auth命令是明文的,破解也很容易。
(5)maxmemory,这个参数比较常见,但是也非常的坑。如果你选择用,有个原则,你是当数据库用还是当缓存用,如果当数据库用,就不要开,如果当缓存用,可以开。曾经有个BUG,多个salve的情况下,会导致擦除主节点的数据。如果你开启这个参数,记得预留一些空间给系统的buffer。
遵循你的使用场景和你对参数的了解。宁愿逐步踩坑逐步解决问题逐步深入了解,也不要盲从的调整参数。
内存使用。如果 Redis 使用的内存超出了可用的物理内存大小,那么 Redis 很可能系统会被杀掉。针对这一点,你可以通过 info 命令对 used_memory 和 used_memory_peak 进行监控,为使用内存量设定阀值,并设定相应的报警机制。当然,报警只是手段,重要的是你得预先计划好,当内存使用量过大后,你应该做些什么,是清除一些没用的冷数据,还是把 Redis 迁移到更强大的机器上去。
持久化。如果因为你的机器或 Redis 本身的问题导致 Redis 崩溃了,那么你唯一的救命稻草可能就是 dump 出来的rdb文件了,所以,对 Redis dump 文件进行监控也是很重要的。可以通过对rdb_last_save_time 进行监控,了解最近一次 dump 数据操作的时间,还可以通过对rdb_changes_since_last_save进行监控来获得如果这时候出现故障,会丢失(即已改变)多少数据。
Keys。通过获取Keyspace中的结果得到各个数据库中key的数量
QPS。即每分钟执行的命令个数,即:(total_commands_processed2-total_commands_processed1)/span,为了实时得到QPS,可以设定脚本在后台运行,记录过去几分钟的total_commands_processed。在计算QPS时,利用过去的信息和当前的信息得出QPS的估计值。
四、如何更好更合理的使用Redis——10个具体应用难点解读
1.Redis与Oracle中存有同一份数据,当数据发生变化时,应用程序是先写Redis然后再同步到Oracle,还是先写Oracle然后再同步到Redis呢,使用何种同步机制可以有效的解决这个时间差中两份数据的不一致性呢?
答:如果你是当数据库用,那就类似于电商抢购场景。抢购的场景中有个需要解决的问题是超买和超卖,意思就是说,我要控制库存数量,而且要保证可用库存的数量为0,不能出现负数。一般是把数据从Oracle刷到Redis,贴合题主的问题,那就是同样有一份数据,当数据变化的时候,是先写Redis还是先写Oracle?是先写Redis,再写Oracle,因为代码层面保证数据的一致性,在高并发情况下,悲观锁机制并不会很友好,而且影响性能。而redis天然的原子性事务,是可以保证数据的一致性。
如果你当缓存用,又要确保数据的强一致性,是可以先写Redis,也可以先写Oracle,如果先写Redis,参考前一段话,采取Redis的强一致性;如果先写Oracle,那就采取悲观锁来实现。
2.目前的监控系统是Python到Oracle取配置信息,经过运算之后再写回Oracle,然后根据阀值来触发告警,在这样的模式之下Redis是否有可以应用的空间呢?
答:当你的监控的需求具备秒级监控的能力后,你的web-db的架构就不再满足了
比如说以下场景
1:基于日志的流式计算
2:监控指标的基线
3:数据的统计分析
4:通用的计算周期
5:多维度的告警规则:如无数据告警、基于同环比的告警、基于基线的告警、
越来越多的监控场景、监控指标、触发器,redis的作用就是提供你更快、更优质的服务
3.我们的系统现在使用了两套Redis;分别用作热点数据缓存、会话保持保存全局ID。热点数据缓存采用的是一主一从三哨兵(分别独立,共五个节点);会话保持采用的是一主三从四个哨兵(共四个节点,每个节点上启动了一个哨兵进程);这个是乙方给的方案,请教大神,这个方案可靠吗?能否使用cluster方案来替代呢?有必要吗?
答:你有两套Redis,A作为热数据缓存,B作为回话保持。
缺点:A有5个节点,B有4个节点,9个节点中只有2个节点是主节点,提供服务,备节点只是冗余,存在比较大的资源浪费。
本文系作者在时代Java发表,未经许可,不得转载。
如有侵权,请联系nowjava@qq.com删除。