什么是Redis持久化?Reids持久化触发条件
- 由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据
- 持久化触发方式有两类:一类是手动触发,另一类是自动触发
Redis 持久化机制
- AOF (Append only file)
把redis所有的改变(增,删,改)操作,追加到日志文件中
- 优点:比较安全,即使redis宕机,也可以迅速恢复原来的数据
- 缺点:会影响redis的性能
- RDB
内存快照,在redis中可以设置
save 900 1 (900s内1次redis操作 会做一次持久化)
save 300 10 (300s内10次redis操作 会做一次持久化)
save 60 10000 (60s内10000次redis操作 会做一次持久化)
- 优点:性能上要比aof好很多
- 缺点:可能会存在数据丢失。例如:11:05分 持久化一次,如果redis在11:04死掉,那么这四分钟的数据,就会丢失
- 混合持久化方式 AOF+RDB
Redis 开启AOF
- redis.conf 中修改
appendonly yes (默认no,关闭)表示是否开启AOF持久化
appendfilename “appendonly.aof” AOF持久化配置文件的名称 - 如果不存在aof文件
-
redis-cli config set appendonly yes
执行的第一条命令开启了 AOF 功能: Redis 会阻塞直到初始 AOF 文件创建完成为止, 之后 Redis 会继续处理命令请求, 并开始将写入命令追加到 AOF 文件末尾 -
redis-cli config set save “”(可选)
执行的第二条命令用于关闭 RDB 功能。 这一步是可选的, 如果你愿意的话, 也可以同时使用 RDB 和 AOF 这两种持久化功能
AOF常用配置总结
在Redis的配置文件中存在三种同步方式,它们分别是:
- appendfsync always #每次有数据修改发生时都会写入AOF文件。默认的是每秒强制写入磁盘一次
- appendfsync everysec #每秒钟同步一次,该策略为AOF的缺省策略。每次执行写操作的时候就强制写入磁盘
- appendfsync no #从不同步。高效但是数据不会被持久化。性能最好但是持久化没法保证
RDB和AOF的优缺点
RDB优势
- 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复
- 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上
- 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了
- 相比于AOF机制,如果数据集很大,RDB的启动效率会更高
RDB劣势
- 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失
- 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟
AOF优势
- 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它
- 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题
- 如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性
- AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建
AOF劣势
- 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
- 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效
二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。rdb这个就更有些 eventually consistent的意思了
缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级
缓存雪崩
- 产生原因:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了
- 解决方案:
- 一般并发量不是特别多的时候,使用最多的解决方案是加锁排队,加锁排队只是为了减轻数据库的压力,并没有提高系统吞吐量
- 给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存
- 二级缓存(慎用)
缓存穿透
- 产生原因:缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有,这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)
- 解决方案:
- 采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力
- 如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟
- 单独设置个缓存区域存储空值,对要查询的key进行预先校验,然后再放行给后面的正常缓存处理逻辑
缓存预热
- 缓存预热就是系统上线后,提前将相关的缓存数据直接加载到缓存系统
- 避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题
- 用户直接查询事先被预热的缓存数据
- 方案
- 直接写个缓存刷新页面,上线时手工操作下
- 数据量不大,可以在项目启动的时候自动进行加载
- 定时刷新缓存
缓存更新
- 除了缓存服务器自带的缓存失效策略之外(Redis默认的有6中策略可供选择)
- 常见的策略有两种
- 定时去清理过期的缓存
- 当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存
第一种的缺点是维护大量缓存的key是比较麻烦的;
第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂!
具体用哪种方案,大家可以根据自己的应用场景来权衡
缓存降级
- 当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务
- 系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级
- 在进行降级之前要对系统进行梳理,筛选可降级服务并设置不同级别服务对应的降级处理
热点数据和冷数据是什么
- 热数据:是需要被计算节点频繁访问的在线类数据。
- 冷数据:是对于离线类不经常访问的数据,比如企业备份数据、业务与操作日志数据、话单与统计数据。
Memcache与Redis的区别都有哪些?
- 存储方式
Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小
Redis有部份存在硬盘上,这样能保证数据的持久性 - 数据支持类型
Memcache对数据类型支持相对简单
Redis有复杂的数据类型 - 使用底层模型不同
它们之间底层实现方式 以及与客户端之间通信的应用协议不一样
Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求 - value大小
redis最大可以达到1GB,而memcache只有1MB
单线程的redis为什么这么快
- 纯内存操作,避免大量访问数据库,减少直接读取磁盘数据,redis将数据储存在内存里面,读写数据的时候都不会受到硬盘 I/O 速度的限制,所以速度快
- 单线程操作,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗
- 采用了非阻塞I/O多路复用机制
- 灵活多样的数据结构
redis内部使用一个redisObject对象来表示所有的key和value。redisObject主要的信息包括数据类型、编码方式、数据指针、虚拟内存等。它包含String,Hash,List,Set,Sorted Set五种数据类型,针对不同的场景使用对应的数据类型,减少内存使用的同时,节省网络流量传输
Redis 中设置过期时间
- EXPIRE : 将键的生存时间设为 ttl 秒
- PEXPIRE :将键的生存时间设为 ttl 毫秒
- EXPIREAT :将键的过期时间设为 timestamp 所指定的秒数时间戳
- PEXPIREAT : 将键的过期时间设为 timestamp 所指定的毫秒数时间戳
如何解决redis的并发竞争key问题
- 分布式锁+时间戳
- 消息队列
Redis 集群方案应该怎么做?都有哪些方案?
- twemproxy,它类似于一个代理方式,使用方法和普通redis无任何区别,设置好它下属的多个redis实例后,使用时在本需要连接redis的地方改为连接twemproxy,它会以一个代理的身份接收请求并使用一致性hash算法,将请求转接到具体redis,将结果返回twemproxy。使用方式简单(相对redis只需修改连接端口),对旧项目扩展的首选
问题:twemproxy自身单端口实例的压力,使用一致性hash后,对redis节点数量改变时候的计算值的改变数据无法自动移动到新的节点 - codis,目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在节点数改变情况下,旧节点数据可恢复到新hash节点
- redis cluster3.0自带的集群,特点在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点
- 在业务代码层实现,起几个毫无关联的redis实例,在代码层,对key进行hash计算,然后去对应的redis实例操作数据。这种方式对hash层代码要求比较高,考虑部分包括,节点失效后的代替算法方案,数据震荡后的自动脚本恢复,实例的监控,等等
有没有尝试进行多机redis 的部署?如何保证数据一致的?
主从复制,读写分离
- redis的复制功能是支持多个数据库之间的数据同步。一类是主数据库(master)一类是从数据库(slave),主数据库可以进行读写操作,当发生写操作的时候自动将数据同步到从数据库,而从数据库一般是只读的,并接收主数据库同步过来的数据,一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库
- 通过redis的复制功能可以很好的实现数据库的读写分离,提高服务器的负载能力。主数据库主要进行写操作,而从数据库负责读操作
- 当一个从数据库启动时,会向主数据库发送sync命令
- 主数据库接收到sync命令后会开始在后台保存快照(执行rdb操作),并将保存期间接收到的命令缓存起来
- 当快照完成后,redis会将快照文件和所有缓存的命令发送给从数据库
- 从数据库收到后,会载入快照文件并执行收到的缓存的命令
对于大量的请求怎么样处理
- redis是一个单线程程序,也就说同一时刻它只能处理一个客户端请求
- redis是通过IO多路复用(select,epoll, kqueue,依据不同的平台,采取不同的实现)来处理多个客户端请求的
- 缓存空数据
- BloomFilter
Redis 常见性能问题和解决方案?
- Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照
- Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度
- Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象
- Redis主从复制的性能问题
- 单点故障问题
解决方案
- Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化
- 如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次
- 为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内
- 尽量避免在压力较大的主库上增加从库
- 为了Master的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关系为:Master<–Slave1<–Slave2<–Slave3…,这样的结构也方便解决单点故障问题,实现Slave对Master的替换,也即,如果Master挂了,可以立马启用Slave1做Master,其他不变
讲解下Redis线程模型
- Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程
- 其中执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的命令不会立刻执行,所有的命令都会进入一个队列中,然后逐个被执行。
- 多个客户端发送的命令的执行顺序是不确定的。但是可以确定的是不会有两条命令被同时执行,不会产生并发问题,这就是Redis的单线程基本模型
为什么Redis的操作是原子性的,怎么保证原子性的?
- Redis的操作之所以是原子性的,是因为Redis是单线程的
- 使用事务保证原子性
Redis事务
- Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中
- redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令
- Redis事务没有隔离级别的概念,批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到
- Redis事务的三个阶段(开始事务,命令入队,执行事务)
Redis支持的数据类型?Reids常用5种数据类型
- string 字符串(可以为整形、浮点型和字符串,统称为元素)
一般做一些复杂的计数功能的缓存 - list 列表(实现队列,元素不唯一,先入先出原则)
可实现队列,栈及有序的数据存储 - set 集合(各不相同的元素)
常用于黑名单,微信抽奖等功能,应用场景多变 - hash hash散列值(hash的key必须是唯一的)
存储二维数据或对象 - sort set 有序集合
做排行榜应用,取TOPN操作;延时任务;做范围查找
Reids6种淘汰策略:
- volatile-lru:从设置了过期时间的数据集中,选择最近最久未使用的数据释放
- allkeys-lru:从数据集中(包括设置过期时间以及未设置过期时间的数据集中),选择最近最久未使用的数据释放
- volatile-random:从设置了过期时间的数据集中,随机选择一个数据进行释放
- allkeys-random:从数据集中(包括了设置过期时间以及未设置过期时间)随机选择一个数据进行入释放
- volatile-ttl:从设置了过期时间的数据集中,选择马上就要过期的数据进行释放操作
- noeviction:不删除任意数据(但redis还会根据引用计数器进行释放),这时如果内存不够时,会直接返回错误
Redis的并发竞争问题如何解决?
- 客户端加锁(synchronized)
- 乐观锁(redis 的命令 watch)
当执行多键值事务操作时,Redis 不仅要求这些键值需要落在同一个 Redis 实例上,还要求落在同一个 slot 上,所以 redis 的事务比较鸡肋
不过可以想办法遵循 redis 内部的分片算法把设计到的所有 key 分到同一个 slot - redis 的 setnx 实现内置的锁
要设置超时时间,防止抢占到锁的客户端因失败、崩溃或其他原因没有办法释放锁而造成死锁
Redis内存划分
- 数据
- 作为数据库,数据是最主要的部分;这部分占用的内存会统计在used_memory中
- Redis使用键值对存储数据,其中的值(对象)包括5种类型,即字符串、哈希、列表、集合、有序集合。这5种类型是Redis对外提供的,实际上,在Redis内部,每种类型可能有2种或更多的内部编码实现;此外,Redis在存储对象时,并不是直接将数据扔进内存,而是会对对象进行各种包装:如redisObject、SDS等
- 进程本身运行需要的内存
- Redis主进程本身运行肯定需要占用内存,如代码、常量池等等;这部分内存大约几兆,在大多数生产环境中与Redis数据占用的内存相比可以忽略。这部分内存不是由jemalloc分配,因此不会统计在used_memory中
- 除了主进程外,Redis创建的子进程运行也会占用内存,如Redis执行AOF、RDB重写时创建的子进程。当然,这部分内存不属于Redis进程,也不会统计在used_memory和used_memory_rss中
- 缓冲内存
- 缓冲内存包括客户端缓冲区、复制积压缓冲区、AOF缓冲区等;其中,客户端缓冲存储客户端连接的输入输出缓冲;复制积压缓冲用于部分复制功能;AOF缓冲区用于在进行AOF重写时,保存最近的写入命令。在了解相应功能之前,不需要知道这些缓冲的细节;这部分内存由jemalloc分配,因此会统计在used_memory中
- 内存碎片
- 内存碎片是Redis在分配、回收物理内存过程中产生的。例如,如果对数据的更改频繁,而且数据之间的大小相差很大,可能导致redis释放的空间在物理内存中并没有释放,但redis又无法有效利用,这就形成了内存碎片。内存碎片不会统计在used_memory中
- 内存碎片的产生与对数据进行的操作、数据的特点等都有关;此外,与使用的内存分配器也有关系:如果内存分配器设计合理,可以尽可能的减少内存碎片的产生。后面将要说到的jemalloc便在控制内存碎片方面做的很好
- 如果Redis服务器中的内存碎片已经很大,可以通过安全重启的方式减小内存碎片:因为重启之后,Redis重新从备份文件中读取数据,在内存中进行重排,为每个数据重新选择合适的内存单元,减小内存碎片
Redis 的主从复制
- 全量同步
Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:
- 从服务器连接主服务器,发送SYNC命令;
- 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
- 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
- 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
- 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
- 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令
- 增量同步
- 主从刚刚连接的时候,进行全量同步
- 全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步
- redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步
- 特点
- 采用异步复制;
- 一个主redis可以含有多个从redis;
- 每个从redis可以接收来自其他从redis服务器的连接;
- 主从复制对于主redis服务器来说是非阻塞的,这意味着当从服务器在进行主从复制同步过程中,主redis仍然可以处理外界的访问请求;
- 主从复制对于从redis服务器来说也是非阻塞的,这意味着,即使从redis在进行主从复制过程中也可以接受外界的查询请求,只不过这时候从redis返回的是以前老的数据,
如果你不想这样,那么在启动redis时,可以在配置文件中进行设置,那么从redis在复制同步过程中来自外界的查询请求都会返回错误给客户端;(虽然说主从复制过程中
对于从redis是非阻塞的,但是当从redis从主redis同步过来最新的数据后还需要将新数据加载到内存中,在加载到内存的过程中是阻塞的,在这段时间内的请求将会被阻,
但是即使对于大数据集,加载到内存的时间也是比较多的); - 主从复制提高了redis服务的扩展性,避免单个redis服务器的读写访问压力过大的问题,同时也可以给为数据备份及冗余提供一种解决方案;
- 为了编码主redis服务器写磁盘压力带来的开销,可以配置让主redis不在将数据持久化到磁盘,而是通过连接让一个配置的从redis服务器及时的将相关数据持久化到磁盘,
不过这样会存在一个问题,就是主redis服务器一旦重启,因为主redis服务器数据为空,这时候通过主从同步可能导致从redis服务器上的数据也被清空
Redis哨兵
- Redis Sentinel 是一个分布式的架构,它本身也是一个独立的 Redis 节点,只不过它不存储数据,只支持部分命令,它能够自动完成故障发现和故障转移,并通知应用方,从而实现高可用
- Redis Sentinel 包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其他 Sentinel 节点进行监控,当发现节点异常时,会对节点做下线标识,如果被标识的是主节点,此时会与其他Sentinel 节点进行协商,当大多数Sentinel 节点都人为主节点不可达时候,会发起选举,选出一个 Sentinel 节点来完成自动故障转移的工作,同时会将这个变化通知给 Redis 的应用方。这个过程是完全自动化的,无需人工干预
- Sentinel 主要提供以下几个功能:
- 监控:定期检测Redis 数据节点、其他 Sentinel 节点是否可达。
- 通知:将故障转移的结果通知给应用方。
- 主节点故障转移:实现从节点晋升为主节点,并维护后续正确的主从关系
配置提供者:客户端在初始化的时候连接 Sentinel 节点集合,从中获取主节点信息。
- 多个 Sentinel 节点来共同判断故障,可以有效防止误判,同时如果个别 Sentinel 节点不可用,整个 Sentinel 节点集合依然是高可用的
redis通讯协议
- RESP协议(二进制安全文本协议)
- TCP
Redis做异步队列
- 一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试
- 如果不用sleep,list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来
- 如果想要生产一次消费多次,可以使用pub/sub主题订阅者模式,可以实现1:N的消息队列,但在消费者下线后,生产的消息会丢失,想要持久化的话,需要使用消息队列如rabbitmq等
事务不支持回滚
- 程序错误导致的数据错误并不会因为回滚而解决
Reids三种不同删除策略
- 定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量
- 惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
- 定期过期:redis 默认是每隔 100ms 就随机抽取一些设置了过期时间的 key,检查其是否过期,如果过期就删除。 注意这里是随机抽取的。每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果
MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中的数据都是热点数据?
- 设置redis内存限制
- 使用恰当的数据淘汰策略加载热数据到内容
Redis常用命令?
redis启动:
- 本地启动:redis-cli
- 远程启动:redis-cli -h host -p port -a password
连接命令
- AUTH password
验证密码是否正确 - ECHO message
打印字符串 - PING
查看服务是否运行 - QUIT
关闭当前连接 - SELECT index
切换到指定的数据库
redis keys命令
- DEL key
- DUMP key
序列化给定的key并返回序列化的值 - EXISTS key
检查给定的key是否存在 - EXPIRE key seconds
为key设置过期时间 - EXPIRE key timestamp
用时间戳的方式给key设置过期时间 - PEXPIRE key milliseconds
设置key的过期时间以毫秒计 - KEYS pattern
查找所有符合给定模式的key - MOVE key db
将当前数据库的key移动到数据库db当中 - PERSIST key
移除key的过期时间,key将持久保存 - PTTL key
以毫秒为单位返回key的剩余过期时间 - TTL key
以秒为单位,返回给定key的剩余生存时间 - RANDOMKEY
从当前数据库中随机返回一个key - RENAME key newkey
修改key的名称 - RENAMENX key newkey
仅当newkey不存在时,将key改名为newkey - TYPE key
返回key所存储的值的类型
reids字符串命令
- SET key value
- GET key
- GETRANGE key start end
返回key中字符串值的子字符 - GETSET key value
将给定key的值设为value,并返回key的旧值 - GETBIT KEY OFFSET
对key所储存的字符串值,获取指定偏移量上的位 - MGET KEY1 KEY2
获取一个或者多个给定key的值 - SETBIT KEY OFFSET VALUE
对key所是存储的字符串值,设置或清除指定偏移量上的位 - SETEX key seconds value
将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。 - SETNX key value
只有在 key 不存在时设置 key 的值。 - SETRANGE key offset value
用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。 - STRLEN key
返回 key 所储存的字符串值的长度。 - MSET key value [key value …]
同时设置一个或多个 key-value 对。 - 、MSETNX key value [key value …]
同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。 - PSETEX key milliseconds value
这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。 - INCR key
将 key 中储存的数字值增一。 - INCRBY key increment
将 key 所储存的值加上给定的增量值(increment) 。 - INCRBYFLOAT key increment
将 key 所储存的值加上给定的浮点增量值(increment) 。 - DECR key
将 key 中储存的数字值减一。 - DECRBY key decrement
key 所储存的值减去给定的减量值(decrement) 。 - APPEND key value
如果 key 已经存在并且是一个字符串, APPEND 命令将 指定value 追加到改 key 原来的值(value)的末尾。
Redis hash 命令
- HDEL key field1 [field2]
删除一个或多个哈希表字段 - HEXISTS key field
查看哈希表 key 中,指定的字段是否存在。 - HGET key field
获取存储在哈希表中指定字段的值。 - HGETALL key
获取在哈希表中指定 key 的所有字段和值 - HINCRBY key field increment
为哈希表 key 中的指定字段的整数值加上增量 increment 。 - HINCRBYFLOAT key field increment
为哈希表 key 中的指定字段的浮点数值加上增量 increment 。 - HKEYS key
获取所有哈希表中的字段 - HLEN key
获取哈希表中字段的数量 - HMGET key field1 [field2]
获取所有给定字段的值 - HMSET key field1 value1 [field2 value2 ]
同时将多个 field-value (域-值)对设置到哈希表 key 中。 - HSET key field value
将哈希表 key 中的字段 field 的值设为 value 。 - HSETNX key field value
只有在字段 field 不存在时,设置哈希表字段的值。 - HVALS key
获取哈希表中所有值 - HSCAN key cursor [MATCH pattern] [COUNT count]
迭代哈希表中的键值对。
Redis 列表命令
- BLPOP key1 [key2 ] timeout
移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 - BRPOP key1 [key2 ] timeout
移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 - BRPOPLPUSH source destination timeout
从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 - LINDEX key index
通过索引获取列表中的元素 - LINSERT key BEFORE|AFTER pivot value
在列表的元素前或者后插入元素 - LLEN key
获取列表长度 - LPOP key
移出并获取列表的第一个元素 - LPUSH key value1 [value2]
将一个或多个值插入到列表头部 - LPUSHX key value
将一个值插入到已存在的列表头部 - LRANGE key start stop
获取列表指定范围内的元素 - LREM key count value
移除列表元素 - LSET key index value
通过索引设置列表元素的值 - LTRIM key start stop
对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 - RPOP key
移除并获取列表最后一个元素 - RPOPLPUSH source destination
移除列表的最后一个元素,并将该元素添加到另一个列表并返回 - RPUSH key value1 [value2]
在列表中添加一个或多个值 - RPUSHX key value
为已存在的列表添加值
Redis 集合命令
- SADD key member1 [member2]
向集合添加一个或多个成员 - SCARD key
获取集合的成员数 - SDIFF key1 [key2]
返回给定所有集合的差集 - SDIFFSTORE destination key1 [key2]
返回给定所有集合的差集并存储在 destination 中 - SINTER key1 [key2]
返回给定所有集合的交集 - SINTERSTORE destination key1 [key2]
返回给定所有集合的交集并存储在 destination 中 - SISMEMBER key member
判断 member 元素是否是集合 key 的成员 - SMEMBERS key
返回集合中的所有成员 - SMOVE source destination member
将 member 元素从 source 集合移动到 destination 集合 - SPOP key
移除并返回集合中的一个随机元素 - SRANDMEMBER key [count]
返回集合中一个或多个随机数 - SREM key member1 [member2]
移除集合中一个或多个成员 - SUNION key1 [key2]
返回所有给定集合的并集 - SUNIONSTORE destination key1 [key2]
所有给定集合的并集存储在 destination 集合中 - SSCAN key cursor [MATCH pattern] [COUNT count]
迭代集合中的元素
Redis 有序集合命令
- ZADD key score1 member1 [score2 member2]
向有序集合添加一个或多个成员,或者更新已存在成员的分数 - ZCARD key
获取有序集合的成员数 - ZCOUNT key min max
计算在有序集合中指定区间分数的成员数 - ZINCRBY key increment member
有序集合中对指定成员的分数加上增量 increment - ZINTERSTORE destination numkeys key [key …]
计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中 - ZLEXCOUNT key min max
在有序集合中计算指定字典区间内成员数量 - ZRANGE key start stop [WITHSCORES]
通过索引区间返回有序集合成指定区间内的成员 - ZRANGEBYLEX key min max [LIMIT offset count]
通过字典区间返回有序集合的成员 - ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT]
通过分数返回有序集合指定区间内的成员 - ZRANK key member
返回有序集合中指定成员的索引 - ZREM key member [member …]
移除有序集合中的一个或多个成员 - ZREMRANGEBYLEX key min max
移除有序集合中给定的字典区间的所有成员 - ZREMRANGEBYRANK key start stop
移除有序集合中给定的排名区间的所有成员 - ZREMRANGEBYSCORE key min max
移除有序集合中给定的分数区间的所有成员 - ZREVRANGE key start stop [WITHSCORES]
返回有序集中指定区间内的成员,通过索引,分数从高到底 - ZREVRANGEBYSCORE key max min [WITHSCORES]
返回有序集中指定分数区间内的成员,分数从高到低排序 - ZREVRANK key member
返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序 - ZSCORE key member
返回有序集中,成员的分数值 - ZUNIONSTORE destination numkeys key [key …]
计算给定的一个或多个有序集的并集,并存储在新的 key 中 - ZSCAN key cursor [MATCH pattern] [COUNT count]
迭代有序集合中的元素(包括元素成员和元素分值)
Redis 发布订阅命令
- PSUBSCRIBE pattern [pattern …]
订阅一个或多个符合给定模式的频道。 - PUBSUB subcommand [argument [argument …]]
查看订阅与发布系统状态。 - PUBLISH channel message
将信息发送到指定的频道。 - PUNSUBSCRIBE [pattern [pattern …]]
退订所有给定模式的频道。 - SUBSCRIBE channel [channel …]
订阅给定的一个或多个频道的信息。 - UNSUBSCRIBE [channel [channel …]]
指退订给定的频道
示例:
redis 127.0.0.1:6379> SUBSCRIBE redisChat
Reading messages… (press Ctrl-C to quit)
- “subscribe”
- “redisChat”
- (integer) 1
现在,我们先重新开启个 redis 客户端,然后在同一个频道 redisChat 发布两次消息,订阅者就能接收到消息。
redis 127.0.0.1:6379> PUBLISH redisChat “Redis is a great caching technique”
(integer) 1
订阅者的客户端会显示如下消息
- “message”
- “redisChat”
- “Redis is a great caching technique”
Redis 事务命令
- DISCARD
取消事务,放弃执行事务块内的所有命令。 - EXEC
执行所有事务块内的命令。 - MULTI
标记一个事务块的开始。 - UNWATCH
取消 WATCH 命令对所有 key 的监视。 - WATCH key [key …]
监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
Redis 脚本命令
- EVAL script numkeys key [key …] arg [arg …]
执行 Lua 脚本。 - EVALSHA sha1 numkeys key [key …] arg [arg …]
执行 Lua 脚本。 - SCRIPT EXISTS script [script …]
查看指定的脚本是否已经被保存在缓存当中。 - SCRIPT FLUSH
从脚本缓存中移除所有脚本。 - SCRIPT KILL
杀死当前正在运行的 Lua 脚本。 - SCRIPT LOAD script
将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。
Redis 服务器命令
- BGREWRITEAOF
异步执行一个 AOF(AppendOnly File) 文件重写操作 - BGSAVE
在后台异步保存当前数据库的数据到磁盘 - CLIENT KILL [ip:port] [ID client-id]
关闭客户端连接 - CLIENT LIST
获取连接到服务器的客户端连接列表 - CLIENT GETNAME
获取连接的名称 - CLIENT PAUSE timeout
在指定时间内终止运行来自客户端的命令 - CLIENT SETNAME connection-name
设置当前连接的名称 - CLUSTER SLOTS
获取集群节点的映射数组 - COMMAND
获取 Redis 命令详情数组 - COMMAND COUNT
获取 Redis 命令总数 - COMMAND GETKEYS
获取给定命令的所有键 - TIME
返回当前服务器时间 - COMMAND INFO command-name [command-name …]
获取指定 Redis 命令描述的数组 - CONFIG GET parameter
获取指定配置参数的值 - CONFIG REWRITE
对启动 Redis 服务器时所指定的 redis.conf 配置文件进行改写 - CONFIG SET parameter value
修改 redis 配置参数,无需重启 - CONFIG RESETSTAT
重置 INFO 命令中的某些统计数据 - DBSIZE
返回当前数据库的 key 的数量 - DEBUG OBJECT key
获取 key 的调试信息 - DEBUG SEGFAULT
让 Redis 服务崩溃 - FLUSHALL
删除所有数据库的所有key - FLUSHDB
删除当前数据库的所有key - INFO [section]
获取 Redis 服务器的各种信息和统计数值 - LASTSAVE
返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示 - MONITOR
实时打印出 Redis 服务器接收到的命令,调试用 - ROLE
返回主从实例所属的角色 - SAVE
同步保存数据到硬盘 - SHUTDOWN [NOSAVE] [SAVE]
异步保存数据到硬盘,并关闭服务器 - SLAVEOF host port
将当前服务器转变为指定服务器的从属服务器(slave server) - SLOWLOG subcommand [argument]
管理 redis 的慢日志 - SYNC
用于复制功能(replication)的内部命令
Redis实现分布式锁
- 互斥性。在任意时刻,只有一个客户端能持有锁
- 不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁
- 具有容错性。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁
- 加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了