auto commit
This commit is contained in:
parent
c38db6259b
commit
b3a7705fb6
118
notes/Redis.md
118
notes/Redis.md
|
@ -1,34 +1,48 @@
|
|||
<!-- GFM-TOC -->
|
||||
* [Redis 是什么](#redis-是什么)
|
||||
* [五种基本类型](#五种基本类型)
|
||||
* [一、Redis 是什么](#一redis-是什么)
|
||||
* [二、五种基本类型](#二五种基本类型)
|
||||
* [1. STRING](#1-string)
|
||||
* [2. LIST](#2-list)
|
||||
* [3. SET](#3-set)
|
||||
* [4. HASH](#4-hash)
|
||||
* [5. ZSET](#5-zset)
|
||||
* [键的过期时间](#键的过期时间)
|
||||
* [发布与订阅](#发布与订阅)
|
||||
* [事务](#事务)
|
||||
* [持久化](#持久化)
|
||||
* [三、键的过期时间](#三键的过期时间)
|
||||
* [四、发布与订阅](#四发布与订阅)
|
||||
* [五、事务](#五事务)
|
||||
* [六、持久化](#六持久化)
|
||||
* [1. 快照持久化](#1-快照持久化)
|
||||
* [2. AOF 持久化](#2-aof-持久化)
|
||||
* [复制](#复制)
|
||||
* [1. 从服务器连接主服务器的过程](#1-从服务器连接主服务器的过程)
|
||||
* [2. 主从链](#2-主从链)
|
||||
* [处理故障](#处理故障)
|
||||
* [分片](#分片)
|
||||
* [事件](#事件)
|
||||
* [1. 事件类型](#1-事件类型)
|
||||
* [2. 事件的调度与执行](#2-事件的调度与执行)
|
||||
* [Redis 与 Memcached 的区别](#redis-与-memcached-的区别)
|
||||
* [Redis 适用场景](#redis-适用场景)
|
||||
* [数据淘汰策略](#数据淘汰策略)
|
||||
* [一个简单的论坛系统分析](#一个简单的论坛系统分析)
|
||||
* [七、复制](#七复制)
|
||||
* [从服务器连接主服务器的过程](#从服务器连接主服务器的过程)
|
||||
* [主从链](#主从链)
|
||||
* [八、处理故障](#八处理故障)
|
||||
* [九、分片](#九分片)
|
||||
* [1. 客户端分片](#1-客户端分片)
|
||||
* [2. 代理分片](#2-代理分片)
|
||||
* [3. 服务器分片](#3-服务器分片)
|
||||
* [十、事件](#十事件)
|
||||
* [事件类型](#事件类型)
|
||||
* [事件的调度与执行](#事件的调度与执行)
|
||||
* [十一、Redis 与 Memcached 的区别](#十一redis-与-memcached-的区别)
|
||||
* [数据类型](#数据类型)
|
||||
* [数据持久化](#数据持久化)
|
||||
* [分布式](#分布式)
|
||||
* [内存管理机制](#内存管理机制)
|
||||
* [十二、Redis 适用场景](#十二redis-适用场景)
|
||||
* [缓存](#缓存)
|
||||
* [消息队列](#消息队列)
|
||||
* [计数器](#计数器)
|
||||
* [好友关系](#好友关系)
|
||||
* [十三、数据淘汰策略](#十三数据淘汰策略)
|
||||
* [十四、一个简单的论坛系统分析](#十四一个简单的论坛系统分析)
|
||||
* [文章信息](#文章信息)
|
||||
* [点赞功能](#点赞功能)
|
||||
* [对文章进行排序](#对文章进行排序)
|
||||
* [参考资料](#参考资料)
|
||||
<!-- GFM-TOC -->
|
||||
|
||||
|
||||
# Redis 是什么
|
||||
# 一、Redis 是什么
|
||||
|
||||
Redis 是速度非常快的非关系型(NoSQL)内存键值数据库,可以存储键和五种不同类型的值之间的映射。
|
||||
|
||||
|
@ -36,7 +50,7 @@ Redis 是速度非常快的非关系型(NoSQL)内存键值数据库,可以
|
|||
|
||||
Redis 支持很多特性,例如将内存中的数据持久化到硬盘中,使用复制来扩展读性能,使用分片来扩展写性能。
|
||||
|
||||
# 五种基本类型
|
||||
# 二、五种基本类型
|
||||
|
||||
| 数据类型 | 可以存储的值 | 操作 |
|
||||
| -- | -- | -- |
|
||||
|
@ -188,7 +202,7 @@ OK
|
|||
2) "982"
|
||||
```
|
||||
|
||||
# 键的过期时间
|
||||
# 三、键的过期时间
|
||||
|
||||
Redis 可以为每个键设置过期时间,当键过期时,会自动删除该键。
|
||||
|
||||
|
@ -196,7 +210,7 @@ Redis 可以为每个键设置过期时间,当键过期时,会自动删除
|
|||
|
||||
过期时间对于清理缓存数据非常有用。
|
||||
|
||||
# 发布与订阅
|
||||
# 四、发布与订阅
|
||||
|
||||
发布与订阅实际上是观察者模式,订阅者订阅了频道之后,发布者向频道发送字符串消息会被所有订阅者接收到。
|
||||
|
||||
|
@ -205,13 +219,13 @@ Redis 可以为每个键设置过期时间,当键过期时,会自动删除
|
|||
1. 如果订阅者读取消息的速度很慢,会使得消息不断积压在发布者的输出缓存区中,造成内存占用过多;
|
||||
2. 如果订阅者在执行订阅的过程中网络出现问题,那么就会丢失断线期间发送的所有消息。
|
||||
|
||||
# 事务
|
||||
# 五、事务
|
||||
|
||||
Redis 最简单的事务实现方式是使用 MULTI 和 EXEC 命令将事务操作包围起来。
|
||||
|
||||
MULTI 和 EXEC 中的操作将会一次性发送给服务器,而不是一条一条发送,这种方式称为流水线,它可以减少客户端与服务器之间的网络通信次数从而提升性能。
|
||||
|
||||
# 持久化
|
||||
# 六、持久化
|
||||
|
||||
Redis 是内存型数据库,为了保证数据在断电后不会丢失,需要将内存中的数据持久化到硬盘上。
|
||||
|
||||
|
@ -239,13 +253,13 @@ always 选项会严重减低服务器的性能;everysec 选项比较合适,
|
|||
|
||||
随着服务器写请求的增多,AOF 文件会越来越大;Redis 提供了一种将 AOF 重写的特性,能够去除 AOF 文件中的冗余写命令。
|
||||
|
||||
# 复制
|
||||
# 七、复制
|
||||
|
||||
通过使用 slaveof host port 命令来让一个服务器成为另一个服务器的从服务器。
|
||||
|
||||
一个从服务器只能有一个主服务器,并且不支持主主复制。
|
||||
|
||||
## 1. 从服务器连接主服务器的过程
|
||||
## 从服务器连接主服务器的过程
|
||||
|
||||
1. 主服务器创建快照文件,发送给从服务器,并在发送期间使用缓冲区记录执行的写命令。快照文件发送完毕之后,开始向从服务器发送存储在缓冲区中的写命令;
|
||||
|
||||
|
@ -253,13 +267,13 @@ always 选项会严重减低服务器的性能;everysec 选项比较合适,
|
|||
|
||||
3. 主服务器每执行一次写命令,就向从服务器发送相同的写命令。
|
||||
|
||||
## 2. 主从链
|
||||
## 主从链
|
||||
|
||||
随着负载不断上升,主服务器可能无法很快地更新所有从服务器,或者重新连接和重新同步从服务器将导致系统超载。为了解决这个问题,可以创建一个中间层来分担主服务器的复制工作。中间层的服务器是最上层服务器的从服务器,又是最下层服务器的主服务器。
|
||||
|
||||
<div align="center"> <img src="../pics//395a9e83-b1a1-4a1d-b170-d081e7bb5bab.png" width="600"/> </div><br>
|
||||
|
||||
# 处理故障
|
||||
# 八、处理故障
|
||||
|
||||
要用到持久化文件来恢复服务器的数据。
|
||||
|
||||
|
@ -267,37 +281,37 @@ always 选项会严重减低服务器的性能;everysec 选项比较合适,
|
|||
|
||||
当主服务器出现故障时,Redis 常用的做法是新开一台服务器作为主服务器,具体步骤如下:假设 A 为主服务器,B 为从服务器,当 A 出现故障时,让 B 生成一个快照文件,将快照文件发送给 C,并让 C 恢复快照文件的数据。最后,让 B 成为 C 的从服务器。
|
||||
|
||||
# 分片
|
||||
# 九、分片
|
||||
|
||||
Redis 中的分片类似于 MySQL 的分表操作,分片是将数据划分为多个部分的方法,对数据的划分可以基于键包含的 ID、基于键的哈希值,或者基于以上两者的某种组合。通过对数据进行分片,用户可以将数据存储到多台机器里面,也可以从多台机器里面获取数据,这种方法在解决某些问题时可以获得线性级别的性能提升。
|
||||
|
||||
假设有 4 个 Reids 实例 R0,R1,R2,R3,还有很多表示用户的键 user:1,user:2,... 等等,有不同的方式来选择一个指定的键存储在哪个实例中。最简单的方式是范围分片,例如用户 id 从 0\~1000 的存储到实例 R0 中,用户 id 从 1001\~2000 的存储到实例 R1 中,等等。但是这样需要维护一张映射范围表,维护操作代价很高。还有一种方式是哈希分片,使用 CRC32 哈希函数将键转换为一个数字,再对实例数量求模就能知道应该存储的实例。
|
||||
|
||||
### 1. 客户端分片
|
||||
## 1. 客户端分片
|
||||
|
||||
客户端使用一致性哈希等算法决定键应当分布到哪个节点。
|
||||
|
||||
### 2. 代理分片
|
||||
## 2. 代理分片
|
||||
|
||||
将客户端请求发送到代理上,由代理转发请求到正确的节点上。
|
||||
|
||||
### 3. 服务器分片
|
||||
## 3. 服务器分片
|
||||
|
||||
Redis Cluster。
|
||||
|
||||
# 事件
|
||||
# 十、事件
|
||||
|
||||
## 1. 事件类型
|
||||
## 事件类型
|
||||
|
||||
### 1.1 文件事件
|
||||
### 1. 文件事件
|
||||
|
||||
服务器有许多套接字,事件产生时会对这些套接字进行操作,服务器通过监听套接字来处理事件。常见的文件事件有:客户端的连接事件;客户端的命令请求事件;服务器向客户端返回命令结果的事件;
|
||||
|
||||
### 1.2 时间事件
|
||||
### 2. 时间事件
|
||||
|
||||
又分为两类:定时事件是让一段程序在指定的时间之内执行一次;周期性时间是让一段程序每隔指定时间就执行一次。
|
||||
|
||||
## 2. 事件的调度与执行
|
||||
## 事件的调度与执行
|
||||
|
||||
服务器需要不断监听文件事件的套接字才能得到待处理的文件事件,但是不能监听太久,否则时间事件无法在规定的时间内执行,因此监听时间应该根据距离现在最近的时间事件来决定。
|
||||
|
||||
|
@ -349,49 +363,49 @@ def main():
|
|||
|
||||
<div align="center"> <img src="../pics//73b73189-9e95-47e5-91d0-9378b8462e15.png"/> </div><br>
|
||||
|
||||
# Redis 与 Memcached 的区别
|
||||
# 十一、Redis 与 Memcached 的区别
|
||||
|
||||
两者都是非关系型内存键值数据库。有以下主要不同:
|
||||
|
||||
### 1. 数据类型
|
||||
## 数据类型
|
||||
|
||||
Memcached 仅支持字符串类型,而 Redis 支持五种不同种类的数据类型,使得它可以更灵活地解决问题。
|
||||
|
||||
### 2. 数据持久化
|
||||
## 数据持久化
|
||||
|
||||
Redis 支持两种持久化策略:RDB 快照和 AOF 日志,而 Memcached 不支持持久化。
|
||||
|
||||
### 3. 分布式
|
||||
## 分布式
|
||||
|
||||
Memcached 不支持分布式,只能通过在客户端使用像一致性哈希这样的分布式算法来实现分布式存储,这种方式在存储和查询时都需要先在客户端计算一次数据所在的节点。
|
||||
|
||||
Redis Cluster 实现了分布式的支持。
|
||||
|
||||
### 4. 内存管理机制
|
||||
## 内存管理机制
|
||||
|
||||
在 Redis 中,并不是所有数据都一直存储在内存中,可以将一些很久没用的 value 交换到磁盘。而 Memcached 的数据则会一直在内存中。
|
||||
|
||||
Memcached 将内存分割成特定长度的块来存储数据,以完全解决内存碎片的问题,但是这种方式会使得内存的利用率不高,例如块的大小为 128 bytes,只存储 100 bytes 的数据,那么剩下的 28 bytes 就浪费掉了。
|
||||
|
||||
# Redis 适用场景
|
||||
# 十二、Redis 适用场景
|
||||
|
||||
### 1. 缓存
|
||||
## 缓存
|
||||
|
||||
适用 Redis 作为缓存,将热点数据放到内存中。
|
||||
|
||||
### 2. 消息队列
|
||||
## 消息队列
|
||||
|
||||
Redis 的 List 类型是双向链表,很适合用于消息队列。
|
||||
|
||||
### 3. 计数器
|
||||
## 计数器
|
||||
|
||||
Redis 这种内存数据库才能支持计数器的频繁读写操作。
|
||||
|
||||
### 4. 好友关系
|
||||
## 好友关系
|
||||
|
||||
使用 set 类型的交集很容易就可以知道两个用户的共同好友。
|
||||
|
||||
# 数据淘汰策略
|
||||
# 十三、数据淘汰策略
|
||||
|
||||
可以设置内存最大使用量,当内存使用量超过时施行淘汰策略,具体有 6 种淘汰策略。
|
||||
|
||||
|
@ -406,7 +420,7 @@ Redis 这种内存数据库才能支持计数器的频繁读写操作。
|
|||
|
||||
如果使用 Redis 来缓存数据时,要保证所有数据都是热点数据,可以将内存最大使用量设置为热点数据占用的内存量,然后启用 allkeys-lru 淘汰策略,将最近最少使用的数据淘汰。
|
||||
|
||||
# 一个简单的论坛系统分析
|
||||
# 十四、一个简单的论坛系统分析
|
||||
|
||||
该论坛系统功能如下:
|
||||
|
||||
|
@ -414,7 +428,7 @@ Redis 这种内存数据库才能支持计数器的频繁读写操作。
|
|||
- 可以对文章进行点赞;
|
||||
- 在首页可以按文章的发布时间或者文章的点赞数进行排序显示;
|
||||
|
||||
### 1. 文章信息
|
||||
## 文章信息
|
||||
|
||||
文章包括标题、作者、赞数等信息,在关系型数据库中很容易构建一张表来存储这些信息,在 Redis 中可以使用 HASH 来存储每种信息以及其对应的值的映射。
|
||||
|
||||
|
@ -422,7 +436,7 @@ Redis 没有关系型数据库中的表这一概念来将同类型的数据存
|
|||
|
||||
<div align="center"> <img src="../pics//7c54de21-e2ff-402e-bc42-4037de1c1592.png" width="400"/> </div><br>
|
||||
|
||||
### 2. 点赞功能
|
||||
## 点赞功能
|
||||
|
||||
当有用户为一篇文章点赞时,除了要对该文章的 votes 字段进行加 1 操作,还必须记录该用户已经对该文章进行了点赞,防止用户点赞次数超过 1。可以建立文章的已投票用户集合来进行记录。
|
||||
|
||||
|
@ -430,7 +444,7 @@ Redis 没有关系型数据库中的表这一概念来将同类型的数据存
|
|||
|
||||
<div align="center"> <img src="../pics//485fdf34-ccf8-4185-97c6-17374ee719a0.png" width="400"/> </div><br>
|
||||
|
||||
### 3. 对文章进行排序
|
||||
## 对文章进行排序
|
||||
|
||||
为了按发布时间和点赞数进行排序,可以建立一个文章发布时间的有序集合和一个文章点赞数的有序集合。(下图中的 score 就是这里所说的点赞数;下面所示的有序集合分值并不直接是时间和点赞数,而是根据时间和点赞数间接计算出来的)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user