diff --git a/notes/Redis.md b/notes/Redis.md index 3f76efb1..bb7a32bb 100644 --- a/notes/Redis.md +++ b/notes/Redis.md @@ -1,32 +1,29 @@ * [Redis 是什么](#redis-是什么) -* [Redis 的五种基本类型](#redis-的五种基本类型) - * [STRING](#string) - * [LIST](#list) - * [SET](#set) - * [HASH](#hash) - * [ZSET](#zset) +* [五种基本类型](#五种基本类型) + * [1. STRING](#1-string) + * [2. LIST](#2-list) + * [3. SET](#3-set) + * [4. HASH](#4-hash) + * [5. ZSET](#5-zset) * [键的过期时间](#键的过期时间) * [发布与订阅](#发布与订阅) * [事务](#事务) * [持久化](#持久化) - * [快照持久化](#快照持久化) - * [AOF 持久化](#aof-持久化) + * [1. 快照持久化](#1-快照持久化) + * [2. AOF 持久化](#2-aof-持久化) * [复制](#复制) - * [从服务器连接主服务器的过程](#从服务器连接主服务器的过程) - * [主从链](#主从链) + * [1. 从服务器连接主服务器的过程](#1-从服务器连接主服务器的过程) + * [2. 主从链](#2-主从链) * [处理故障](#处理故障) * [分片](#分片) * [事件](#事件) - * [事件类型](#事件类型) - * [事件的调度与执行](#事件的调度与执行) + * [1. 事件类型](#1-事件类型) + * [2. 事件的调度与执行](#2-事件的调度与执行) * [Redis 与 Memcached 的区别](#redis-与-memcached-的区别) * [Redis 适用场景](#redis-适用场景) * [数据淘汰策略](#数据淘汰策略) * [一个简单的论坛系统分析](#一个简单的论坛系统分析) - * [文章信息](#文章信息) - * [点赞功能](#点赞功能) - * [对文章进行排序](#对文章进行排序) * [参考资料](#参考资料) @@ -39,7 +36,7 @@ Redis 是速度非常快的非关系型(NoSQL)内存键值数据库,可以 Redis 支持很多特性,例如将内存中的数据持久化到硬盘中,使用复制来扩展读性能,使用分片来扩展写性能。 -# Redis 的五种基本类型 +# 五种基本类型 | 数据类型 | 可以存储的值 | 操作 | | -- | -- | -- | @@ -51,7 +48,7 @@ Redis 支持很多特性,例如将内存中的数据持久化到硬盘中, > [What Redis data structures look like](https://redislabs.com/ebook/part-1-getting-started/chapter-1-getting-to-know-redis/1-2-what-redis-data-structures-look-like/) -## STRING +## 1. STRING

@@ -66,12 +63,10 @@ OK (nil) ``` -## LIST +## 2. LIST

- - ```html > rpush list-key item (integer) 1 @@ -96,7 +91,7 @@ OK 2) "item" ``` -## SET +## 3. SET

@@ -130,7 +125,7 @@ OK 2) "item3" ``` -## HASH +## 4. HASH

@@ -161,8 +156,7 @@ OK 2) "value1" ``` -## ZSET - +## 5. ZSET

@@ -221,7 +215,7 @@ MULTI 和 EXEC 中的操作将会一次性发送给服务器,而不是一条 Redis 是内存型数据库,为了保证数据在断电后不会丢失,需要将内存中的数据持久化到硬盘上。 -## 快照持久化 +## 1. 快照持久化 将某个时间点的所有数据都存放到硬盘上。 @@ -229,7 +223,7 @@ Redis 是内存型数据库,为了保证数据在断电后不会丢失,需 如果系统发生故障,将会丢失最后一次创建快照之后的数据。并且如果数据量很大,保存快照的时间也会很长。 -## AOF 持久化 +## 2. AOF 持久化 AOF 持久化将写命令添加到 AOF 文件(Append Only File)的末尾。 @@ -251,7 +245,7 @@ always 选项会严重减低服务器的性能;everysec 选项比较合适, 一个从服务器只能有一个主服务器,并且不支持主主复制。 -## 从服务器连接主服务器的过程 +## 1. 从服务器连接主服务器的过程 1. 主服务器创建快照文件,发送给从服务器,并在发送期间使用缓冲区记录执行的写命令。快照文件发送完毕之后,开始向从服务器发送存储在缓冲区中的写命令; @@ -259,7 +253,7 @@ always 选项会严重减低服务器的性能;everysec 选项比较合适, 3. 主服务器每执行一次写命令,就向从服务器发送相同的写命令。 -## 主从链 +## 2. 主从链 随着负载不断上升,主服务器可能无法很快地更新所有从服务器,或者重新连接和重新同步从服务器将导致系统超载。为了解决这个问题,可以创建一个中间层来分担主服务器的复制工作。中间层的服务器是最上层服务器的从服务器,又是最下层服务器的主服务器。 @@ -279,31 +273,31 @@ Redis 中的分片类似于 MySQL 的分表操作,分片是将数据划分为 假设有 4 个 Reids 实例 R0,R1,R2,R3,还有很多表示用户的键 user:1,user:2,... 等等,有不同的方式来选择一个指定的键存储在哪个实例中。最简单的方式是范围分片,例如用户 id 从 0\~1000 的存储到实例 R0 中,用户 id 从 1001\~2000 的存储到实例 R1 中,等等。但是这样需要维护一张映射范围表,维护操作代价很高。还有一种方式是哈希分片,使用 CRC32 哈希函数将键转换为一个数字,再对实例数量求模就能知道应该存储的实例。 -**客户端分片** +### 1. 客户端分片 客户端使用一致性哈希等算法决定键应当分布到哪个节点。 -**代理分片** +### 2. 代理分片 将客户端请求发送到代理上,由代理转发请求到正确的节点上。 -**服务器分片** +### 3. 服务器分片 Redis Cluster。 # 事件 -## 事件类型 +## 1. 事件类型 -**文件事件** +### 1.1 文件事件 服务器有许多套接字,事件产生时会对这些套接字进行操作,服务器通过监听套接字来处理事件。常见的文件事件有:客户端的连接事件;客户端的命令请求事件;服务器向客户端返回命令结果的事件; -**时间事件** +### 1.2 时间事件 又分为两类:定时事件是让一段程序在指定的时间之内执行一次;周期性时间是让一段程序每隔指定时间就执行一次。 -## 事件的调度与执行 +## 2. 事件的调度与执行 服务器需要不断监听文件事件的套接字才能得到待处理的文件事件,但是不能监听太久,否则时间事件无法在规定的时间内执行,因此监听时间应该根据距离现在最近的时间事件来决定。 @@ -359,21 +353,21 @@ def main(): 两者都是非关系型内存键值数据库。有以下主要不同: -**数据类型** +### 1. 数据类型 Memcached 仅支持字符串类型,而 Redis 支持五种不同种类的数据类型,使得它可以更灵活地解决问题。 -**数据持久化** +### 2. 数据持久化 Redis 支持两种持久化策略:RDB 快照和 AOF 日志,而 Memcached 不支持持久化。 -**分布式** +### 3. 分布式 Memcached 不支持分布式,只能通过在客户端使用像一致性哈希这样的分布式算法来实现分布式存储,这种方式在存储和查询时都需要先在客户端计算一次数据所在的节点。 Redis Cluster 实现了分布式的支持。 -**内存管理机制** +### 4. 内存管理机制** 在 Redis 中,并不是所有数据都一直存储在内存中,可以将一些很久没用的 value 交换到磁盘。而 Memcached 的数据则会一直在内存中。 @@ -381,19 +375,19 @@ Memcached 将内存分割成特定长度的块来存储数据,以完全解决 # Redis 适用场景 -**缓存** +### 1. 缓存 适用 Redis 作为缓存,将热点数据放到内存中。 -**消息队列** +### 2. 消息队列 Redis 的 List 类型是双向链表,很适合用于消息队列。 -**计数器** +### 3. 计数器 Redis 这种内存数据库才能支持计数器的频繁读写操作。 -**好友关系** +### 4. 好友关系 使用 set 类型的交集很容易就可以知道两个用户的共同好友。 @@ -420,7 +414,7 @@ Redis 这种内存数据库才能支持计数器的频繁读写操作。 - 可以对文章进行点赞; - 在首页可以按文章的发布时间或者文章的点赞数进行排序显示; -## 文章信息 +### 1. 文章信息 文章包括标题、作者、赞数等信息,在关系型数据库中很容易构建一张表来存储这些信息,在 Redis 中可以使用 HASH 来存储每种信息以及其对应的值的映射。 @@ -428,7 +422,7 @@ Redis 没有关系型数据库中的表这一概念来将同类型的数据存

-## 点赞功能 +### 2. 点赞功能 当有用户为一篇文章点赞时,除了要对该文章的 votes 字段进行加 1 操作,还必须记录该用户已经对该文章进行了点赞,防止用户点赞次数超过 1。可以建立文章的已投票用户集合来进行记录。 @@ -436,7 +430,7 @@ Redis 没有关系型数据库中的表这一概念来将同类型的数据存

-## 对文章进行排序 +### 3. 对文章进行排序 为了按发布时间和点赞数进行排序,可以建立一个文章发布时间的有序集合和一个文章点赞数的有序集合。(下图中的 score 就是这里所说的点赞数;下面所示的有序集合分值并不直接是时间和点赞数,而是根据时间和点赞数间接计算出来的)