Redis小结


Redis基础

一、简介

Redis是一个完全开源免费的高性能key-value数据库

  • Redis支持将数据持久化到硬盘上,在重启时可以再次加载使用,不像Memcached断电后数据丢失;
  • Redis的数据类型丰富,包括:String、list、set、zset(有序集合)、hash;
  • Redis支持master-slave(主从备份)模式的备份;
  • Redis单机使用单线程模式运行,所有的命令都在队列中等待执行

二、数据类型

Redis支持五中数据类型:String(字符串)、list(列表)、set(集合)、zset(有序集合)、hash(哈希)
1. String(字符串)
字符串是Redis最基本的数据类型,且是二进制安全的,所以可以存储任何数据,一个键值对最大存储512MB;

redis 127.0.0.1:6379> SET name "rambo"
OK
redis 127.0.0.1:6379> GET name
"rambo"

大部分情况在使用Redis时,都是将对象序列化String,进行存储。
2. Hash(哈希)
Redis的Hash是一个键值对的集合,将对象存储在Redis中十分简单。

127.0.0.1:6379> HMSET user username runoob password runoob   points 200
OK
127.0.0.1:6379> HGETALL user
1) "username"
2) "runoob"
3) "password"
4) "runoob"
5) "points"
6) "200"       

“user”是这个hash的name,通过这个name来获取该hash的value。
3. List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(lpush)或者尾部(rpush);从头部移除并获取列表的第一个元素(lpop)。
4. Set(集合)
Redis的Set是string类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
5. ZSET(有序集合)

zadd 命令:zadd key score member
添加元素到集合,元素在集合中存在则更新对应score

三、Redis命令

参见Redis 命令

高级特性

一、持久化&&主从复制

持久化

Redis的持久化有两种方式:RDB(内存快照)和AOF(文件追加)
1. RDB

该持久化方式能够在指定的时间间隔对数据进行快照存储,默认情况下,存储在”dump.rdb”的二进制文件中。
触发方式有两种:

  • 自动保存:设置触发条件”N秒内数据集至少有M个改动”,如save 60 1000,即表示 满足60 秒内有至少有 1000 个键被改动,这一条件时, 自动保存一次数据集
  • 手动保存:客户端调用SAVE或BGSAVE进行同步/异步保存。

工作方式:

当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:

  • Redis 调用forks. 同时拥有父进程和子进程。
  • 子进程将数据集写入到一个临时 RDB 文件中。
  • 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

这种工作方式使得Redis可以从写时复制(copy-on-write)机制中获益。

RDB的优缺点如下:

  • 优点
    • RDB文件紧凑,非常适用于数据集的备份,指定的时间间隔进行备份,可以有不同时间版本的数据集用于数据恢复;
    • RDB文件是单一的,方便进行多端传输,进行灾备;
    • 备份文件的工作由父进程fork的子进程来进行,可以最大化性能;
    • 相比AOF,RDB在恢复大的数据集时,速度更快。
  • 缺点
    • 由于RDB是在指定的时间间隔进行快照,所以在Redis意外停止工作的时候,会丢失几分钟的数据
    • RDB需要经常fork子进程来对内存进行快照存储,当数据集较大的时候,fork的过程是非常耗时的,同时,fork的子进程需要和父进程一样的内存来存储相应的数据集。所以,耗时导致父进程对客户端的响应延时,内存消耗导致成本提高。

这种持久化方式被称为快照 snapshotting。
2. AOF

该方式记录每次对服务端写的操作,以Redis协议将写操作追加到AOF文件末尾,由于每次写命令都会被记录,所以AOF的文件的体积通常较大,可以使用BGREWRITEAOF命令重写AOF文件,去除重复无用的命令。

开启AOF的方式:appendonly yes,在配置文件redis.conf中。
追加的频次:

  • 每次有新命令追加到AOF文件时都进行一次fsync:非常慢&安全;
  • 每秒进行一次fsync:足够快,发生故障时只丢失1S的数据,推荐用法;
  • 从不fsync:将数据交给操作系统来处理,更快、更不安全。

工作方式:

AOF 重写和 RDB 创建快照一样,都巧妙地利用了写时复制机制:

  • Redis 执行 fork() ,现在同时拥有父进程和子进程。
  • 子进程开始将新 AOF 文件的内容写入到临时文件。
  • 对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF文件的末尾,这样样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
  • 当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。
  • 搞定!现在 Redis原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。

优缺点:

  • 优点
    • 不同的fsync策略使Redis更加耐久;
    • AOF文件可以使用redis-check-aof工具来修复某些原因导致的文件问题;
    • Redis可以自动地调用BGREWRITEAOF命令来重写AOF文件以减少其体积,在重写过程中文件是绝对安全的;
    • AOF文件简单易懂。
  • 缺点
    • 相同数据集的AOF文件大于RDB文件;
    • 根据所选择的fsync策略,AOF的速度可能慢于RDB。

主从复制、读写分离

Redis复制很简单易用,它通过配置slaveof ip port将一台Redis实例设置成某台实例的从服务器

特点如下:

  • 一个Master可以有多个Slaves。
  • Slaves能过接口其他slave的链接,除了可以接受同一个master下面slaves的链接以外,还可以接受同一个结构图中的其他slaves的链接。
  • redis复制是在master段是非阻塞的,这就意味着master在同一个或多个slave端执行同步的时候还可以接受查询。
  • 复制在slave端也是非阻塞的,假设你在redis.conf中配置redis这个功能,当slave在执行的新的同步时,它仍可以用旧的数据信息来提供查询,否则,你可以配置当redis slaves去master失去联系是,slave会给发送一个客户端错误。
  • 为了有多个slaves可以做只读查询,复制可以重复2次,甚至多次,具有可扩展性(例如:slaves对话与重复的排序操作,有多份数据冗余就相对简单了)。
  • 通过复制可以避免master全量写硬盘的消耗:只要配置 master的配置文件redis.conf来“避免保存”(注释掉所有”save”命令),然后连接一个用来持久化数据的slave即可。

配置方式

  • 在配置文件或启动时:slaveof ip port
  • 密码验证:masterauth <password>

工作方式

  • Slave在连接到Master上时,会发送一个Sync命令,然后Master开始后台保存,收集所有对修改数据的命令;
  • 当后台保存完成,Master会将这个数据文件(AOF?RDB?)传送到Slave,然后Slave保存在磁盘,加载到内存中;
  • Master接着发送给Slave收集到的所有的修改数据的命令(缓存在缓冲区),这好比一个流命令,是Redis协议本身来实现的。

当配置了从节点后,可以使从节点负责客户端的读服务,主节点专注于写服务,从而提高实例的响应性能。

二、Redis集群&&哨兵

三、事务&&分布式锁

Redis事务

事务的四大特性:ACID,原子性,一致性,隔离性,持久性。

Redis事务可以一次执行多个命令, 并且带有以下两个重要的保证:

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

Redis原子性:

  • Redis单机服务是单进程运行,所有的命令都需要入队列排队等待执行,所以同一时刻只有一个命令在执行;
  • Redis的基础命令都是原子性的;
  • Redis可以使用MULTIEXEC命令来组装一组原子性操作的命令,MULTI用来开启一个事务,EXEC用来执行该事务。

用法:

  • MULTI 命令用于开启一个事务,它总是返回 OK 。
  • MULTI 执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中, 当 EXEC命令被调用时, 所有队列中的命令才会被执行。
  • 另一方面, 通过调用 DISCARD , 客户端可以清空事务队列, 并放弃执行事务。

Redis的事务不支持错误回滚,事务队列中失败的命令会返回错误信息,只执行成功的命令。

利用Redis实现分布式锁

我们可以使用Redis实现分布式锁,利用原子操作SETNX实现自旋锁,参见SETNX key value

因为Redis的SETNX命令是原子性的,可以根据此命令设置一个公共的key,所以节点在操作临界区数据前先自旋地调用该命令,如果返回成功则进入临界区,否则自旋。
问题和优化:

  • 获得锁的进程挂掉了,没有释放锁,导致其他进程不断自旋:设置key的超时时间,超时后自动释放锁
  • SETNXEXPIRE非原子性操作:LUA脚本将其原子化

目前并没有更加优雅的处理方式去解决进程挂掉的问题。

四、其他

  1. 管道
    参见:Redis 管道技术
  2. 发布&订阅
    参见发布&订阅
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值