Redis 常被称作是一款数据结构服务器(data structure server)。Redis 的键值可以包括字符串(strings)类型,同时它还包括哈希(hashes)、列表(lists)、集合(sets)和 有序集合(sorted sets)等数据类型。
对于这些数据类型,你可以执行原子操作。例如:对字符串进行附加操作(append);递增哈希中的值;向列表中增加元素;计算集合的交集、并集与差集等。
Redis keys 是采用二进制安全,这就意味着你可以使用任何二进制序列作为重点,比如:“foo” 可以联系一个 JPEG 文件;空字符串也是一个有效的密钥。
Redis 的优点
- 性能极高:Redis 能支持超过 100K+ 每秒的读写频率
- 原子:Redis 的所有操作都是原子性的,同时 Redis 还支持对几个操作全并后的原子性执行。
- 丰富的特性:Redis 还支持 publish/subscribe,通知,key 过期等等特性
建议:涉及到客户端连接是需要指定密码的(由于 redis 速度相当的快,一秒钟可以 150K次的密码尝试,所以需要设置一个强度很大的密码)。
数据类型简介
- string
Redis 字符串是二进制安全的,这意味着一个 Redis 字符串能包含任意类型的数据,例如: 一张经过 base64 编码的图片或者一个序列化的 Ruby 对象。通过这样的方式,Redis 的字符串可以支持任意形式的数据,但是对于过大的文件不适合存入 redis,一方面系统内存有限,另外一方面字符串类型的值最多能存储 512M 字节的内容。
- List
Redis 列表是简单的字符串列表,按照插入顺序排序。
一个列表最多可以包含 4294967295(2 的 32 次方减一)个元素,这意味着它可以容纳海量的信息,最终瓶颈一般都取决于服务器内存大小。
事实上,在高级的企业架构当中,会把缓存服务器分离开来,因为数据库服务器和缓存服务器的特点各异,比如对于数据库服务器应该用更快、更大的硬盘,而缓存专用服务器则偏向内存性能,一般都是 64GB 起步。
List的阻塞操作:Redis 提供了阻塞式访问 brpop 和 blpop 命令。用户可以在获取数据不存在时阻塞请求队列,如果在时限内获得数据则立即返回,如果超时还没有数据则返回 nil。
- Hash
Redis 哈希是字符串字段和字符串值之间的映射,因此它们是展现对象的完美数据类型。
一个带有一些字段的 hash 仅仅需要一块很小的空间存储,因此你可以存储数以百万计的对象在一个小的 Redis 实例中。哈希主要用来表现对象,它们有能力存储很多对象,因此你可以将哈希用于许多其它的任务。
- Set
Redis 集合是一个无序的字符串集合。你可以以 O(1) 的时间复杂度(无论集合中有多少元素时间复杂度都是常量)完成添加、删除以及测试元素是否存在。
Redis 集合拥有令人满意的不允许包含相同成员的属性,多次添加相同的元素,最终在集合里只会有一个元素,这意味着它可以非常方便地对数据进行去重操作,一个 Redis 集合的非常有趣的事情是它支持一些服务端的命令从现有的集合出发去进行集合运算,因此你可以在非常短的时间内进行合并(unions),求交集(intersections),找出不同的元素(differences of sets)
- ZSet
Redis 有序集合与普通集合非常相似,是一个没有重复元素的字符串集合。不同之处是有序集合的每一个成员都关联了一个权值,这个权值被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是权值可以是重复的。
使用有序集合你可以以非常快的速度 O(log(N)) 添加、删除和更新元素。因为元素是有序的,所以你也可以很快的根据权值(score)或者次序(position)来获取一个范围的元素。访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。在有序集合中,你可以很快捷的访问一切你需要的东西:有序的元素,快速的存在性测试,快速访问集合的中间元素!简而言之使用有序集合你可以完成许多对性能有极端要求的任务,而那些任务使用其它类型的数据库真的是很难完成的。
系统管理
info [section]
:查询 Redis 相关信息
其命令选项有如下:
- server: Redis server 的常规信息
- clients: Client 的连接选项
- memory: 存储占用相关信息
- persistence: RDB and AOF 相关信息
- stats: 常规统计
- replication: Master/Slave 请求信息
- cpu: CPU 占用信息统计
- cluster: Redis 集群信息
- keyspace: 数据库信息统计
- all: 返回所有信息
- default: 返回常规设置信息
- 无参: 返回所有信息
主从复制
为了分担服务器压力,会在特定情况下部署多台服务器分别用于缓存的读和写操作,用于写操作的服务器称为主服务器,用于读操作的服务器称为从服务器。
从服务器通过 psync 操作同步主服务器的写操作,并按照一定的时间间隔更新主服务器上新写入的内容。
- Redis 主从复制的过程
- Slave 与 Master 建立连接,发送 psync 同步命令。
- Master 会启动一个后台进程,将数据库快照保存到文件中,同时 Master 主进程会开始收集新的写命令并缓存。
- 后台完成保存后,就将此文件发送给 Slave。
- Slave 将此文件保存到磁盘上。
- Redis 主从复制特点
- 可以拥有多个 Slave。
- 多个 Slave 可以连接同一个 Master 外,还可以连接到其它的 Slave。(当 Master 宕机后,相连的 Slave转变为 Master)。
- 主从复制不会阻塞 Master,在同步数据时, Master 可以继续处理 Client 请求。
- 提高了系统的可伸缩性。
主从复制是不会阻塞 Master 的,就是说 Slave 在从 Master 复制数据时,Master 的删改插入等操作继续进行不受影响。
如果在同步过程中,主服务器修改了东西,而同步到从服务器上的内容是修改前的。这时候就会出现时间差,即修改了过后,在访问网站的时候还是原来的数据,这是因为从服务器还未同步最新的更改,这也就意味着非阻塞式的同步只能应用于对读数据延迟接受度较高的场景。
要建立这样一个主从关系的缓存服务器,只需要在 Slave 端执行命令:
# SLAVEOF IPADDRESS:PORT
SLAVEOF 127.0.0.1:6379
如果主服务器设置了连接密码,就需要在从服务器中事先设置好:
config set masterauth <password>
这样,当前服务器就作为 127.0.0.1:6379 下的一个从服务器,它将定期从该服务器复制数据到自身。
在以前的版本中(2.8 以前),你应该慎用 redis 的主从复制功能,因为它的同步机制效率低下,可以想象每一次短线重连都要复制主服务器上的全部数据,算上网络通讯所耗费的时间,反而可能达不到通过 redis 缓存来提升应用响应速度的效果。但是幸运的是,官方在 2.8 以后推出了解决方案,通过部分同步来解决大量的重复操作。
这需要主服务器和从服务器都至少达到 2.8 的版本要求。
事务处理
Redis 的事务处理比较简单。只能保证 client 发起的事务中的命令可以连续的执行,而且不会插入其它的 client 命令,当一个 client 在连接中发出 multi 命令时,这个连接就进入一个事务的上下文,该连接后续的命令不会执行,而是存放到一个队列中,当执行 exec 命令时,redis 会顺序的执行队列中的所有命令。
需要注意的是,redis 对于事务的处理方式比较特殊,它不会在事务过程中出错时恢复到之前的状态,这在实际应用中导致我们不能依赖 redis 的事务来保证数据一致性。
持久化机制
内存和磁盘的区别除了速度差别以外,还有就是内存中的数据会在重启之后消失,持久化的作用就是要将这些数据长久存到磁盘中以支持长久使用。
Redis 是一个支持持久化的内存数据库,Redis 需要经常将内存中的数据同步到磁盘来保证持久化。
Redis 支持两种持久化方式:
1、snapshotting(快照):将数据存放到文件里,默认方式。
是将内存中的数据以快照的方式写入到二进制文件中,默认文件 dump.rdb,可以通过配置设置自动做快照持久化的方式。可配置 Redis 在 n 秒内如果超过 m 个 key 被修改就自动保存快照。比如:
save 900 1
:900 秒内如果超过 1 个 key 被修改,则发起快照保存。
save 300 10
:300 秒内如果超过 10 个 key 被修改,则快照保存。
2、Append-only file(缩写为 aof):将读写操作存放到文件中。
由于快照方式在一定间隔时间做一次,所以如果 Redis 意外 down 掉的话,就会丢失最后一次快照后的所有修改。
aof 比快照方式有更好的持久化性,是由于使用 aof 时,redis 会将每一个收到的写命令都通过 write 函数写入到文件中,当 redis 启动时会通过重新执行文件中保存的写命令来在内存中重新建立整个数据库的内容。
由于 os 会在内核中缓存 write 做的修改,所以可能不是立即写到磁盘上,这样 aof 方式的持久化也还是有可能会丢失一部分数据。可以通过配置文件告诉 redis 我们想要通过 fsync 函数强制 os 写入到磁盘的时机。
配置文件中的可配置参数:
appendonly yes //启用 aof 持久化方式
# appendfsync always //收到写命令就立即写入磁盘,最慢,但是保证了数据的完整持久化
appendfsync everysec //每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中
# appendfsync no //完全依赖 os,性能最好,持久化没有保证
在 redis-cli 的命令中,save
命令是将数据写入磁盘中。
> help save
> save
参考
https://www.redis.net.cn/order/
https://www.shiyanlou.com/courses/106