From d6439f832811a02979c3d9b1c827f20f0ac299cb Mon Sep 17 00:00:00 2001 From: heibaiying <2806718453@qq.com> Date: Mon, 15 Jul 2019 15:09:16 +0800 Subject: [PATCH] =?UTF-8?q?Redis=20=E6=8C=81=E4=B9=85=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- notes/MongoDB_分片.md | 0 notes/MongoDB_基础操作.md | 0 notes/MongoDB_复制集.md | 0 notes/MongoDB_索引.md | 0 notes/MongoDB_聚合.md | 0 notes/Redis_持久化.md | 111 ++++++++++++++++++ .../installation/MongoDB单机环境搭建.md | 84 +++++++++++++ pictures/mongodb-version-select.png | Bin 0 -> 11785 bytes 8 files changed, 195 insertions(+) create mode 100644 notes/MongoDB_分片.md create mode 100644 notes/MongoDB_基础操作.md create mode 100644 notes/MongoDB_复制集.md create mode 100644 notes/MongoDB_索引.md create mode 100644 notes/MongoDB_聚合.md create mode 100644 notes/Redis_持久化.md create mode 100644 notes/installation/MongoDB单机环境搭建.md create mode 100644 pictures/mongodb-version-select.png diff --git a/notes/MongoDB_分片.md b/notes/MongoDB_分片.md new file mode 100644 index 0000000..e69de29 diff --git a/notes/MongoDB_基础操作.md b/notes/MongoDB_基础操作.md new file mode 100644 index 0000000..e69de29 diff --git a/notes/MongoDB_复制集.md b/notes/MongoDB_复制集.md new file mode 100644 index 0000000..e69de29 diff --git a/notes/MongoDB_索引.md b/notes/MongoDB_索引.md new file mode 100644 index 0000000..e69de29 diff --git a/notes/MongoDB_聚合.md b/notes/MongoDB_聚合.md new file mode 100644 index 0000000..e69de29 diff --git a/notes/Redis_持久化.md b/notes/Redis_持久化.md new file mode 100644 index 0000000..d68da32 --- /dev/null +++ b/notes/Redis_持久化.md @@ -0,0 +1,111 @@ +# Redis 持久化 + +## 一、数据持久化 + +默认情况下 Redis 的数据都是保存在内存中,为避免 Redis 进程意外退出而导致数据丢失的问题,Redis 提供了 RDB 和 AOF 两种方式来实现数据的持久化存储。 + +## 二、RDB 机制 + +RDB 机制是以指定的时间间隔将 Redis 中的数据生成快照并保存到硬盘中,它更适合于定时备份数据的应用场景。可以通过手动或者自动的方式来触发 RDB 机制: + +### 2.1 手动触发 + +可以通过以下两种方式来手动触发 RDB 机制: + ++ **save** :save 命令会阻塞当前 Redis 服务,直到 RDB 备份过程完成,在这个时间内,客户端的所有查询都会被阻塞; ++ **bgsave** :Redis 进程会 fork 出一个子进程,阻塞只会发生在 fork 阶段,之后持久化的操作则由子进程来完成。 + +### 2.2 自动触发 + +除了手动使用命令触发外,在某些场景下也会自动触发 Redis 的 RDB 机制: + ++ 在 `redis.conf` 中配置了 `save m n` ,表示如果在 m 秒内存在了 n 次修改操作时,则自动触发`bgsave`; ++ 如果从节点执行全量复制操作,则主节点自动执行`bgsave`,并将生成的 RDB 文件发送给从节点; ++ 执行 `debug reload` 命令重新加载 Redis 时,会触发`save`操作; ++ 执行 `shutdown` 命令时候,如果没有启用 AOF 持久化则默认采用`bgsave`进行持久化。 + +### 2.3 相关配置 + +**1. 文件目录** + +RDB 文件默认保存在 Redis 的工作目录下,默认文件名为 `dump.rdb`,可以通过静态或动态方式修改: + ++ 静态配置:通过修改 `redis.conf` 中的工作目录`dir`和数据库存储文件名`dbfilename`两个配置 + ++ 动态修改:通过在命令行中执行以下命令 + + ```shell + config set dir{newDir} + config set dbfilename{newFileName} + ``` + +**2. 压缩算法** + +Redis 默认采用 LZF 算法对生成的 RDB 文件做压缩处理, 这样可以减少占用空间和网络传输的数据量,但是压缩过程会耗费 CPU 的计算资源, 你可以按照你的实际情况,选择是否启用。可以通过修改 `redis.conf` 中的`rdbcompression `配置项或使用以下命令来进行动态修改: + +```shell +config set rdbcompression{yes|no} +``` + +## 三、AOF 机制 + +AOF 是 Redis 提供的另外一种持久化的方式,它以独立日志的方式记录每次写命令,重启时再重新执行 AOF 文件中的命令,从而达到恢复数据的命令。 + +### 3.1 执行原理 + +开启 AOF 机制后,所有的写入命令都会追加到 aof_buf 缓冲区中,并按照指定的策略定时将缓冲区中的数据同步到磁盘上。 AOF 除了记录每条命令外,还会在适当的时候 fork 出一个子进程对 AOF 文件进行重写,在重写过程中,Redis 会将可以合并的语句进行合并,将无效的语句进行删除,从而减小 AOF 文件的体积,以便减少文件的占用空间和方便在数据恢复时能够更快的进行加载。 + +### 3.2 同步策略 + +Redis 提供了三种同步策略,用于控制 AOF 缓冲区同步数据到磁盘上的行为,由参数`appendfsync `控制: + +| 可选配置 | 说明 | +| -------- | ------------------------------------------------------------ | +| always | 命令写入 aof_buf 后就调系统 fsync 操作同步到 AOF 文件 | +| everysec | 命令写入 aof_buf 后就调用系统的 write 操作,但 fsync 同步文件的操作则由专门线程每秒调用一次 | +| no | 命令写入 aof_buf 后就调用系统的 write 操作,不对 AOF 文件做 fsync 同步,同步操作由操作系统负责,通常同步周期最长为30秒 | + +write 和 fsync 操作说明: + +- write 操作会触发延迟写机制,Linux 在内核提供页缓冲区用来提高硬盘的 IO 性能,write 操作在写入系统缓冲区后直接返回。同步操作依赖于系统调度机制, 例如:缓冲区页空间写满或达到特定时间周期。 同步文件之前, 如果此时系统故障宕机, 缓冲区内数据将丢失。 +- fsync 针对单个文件操作,做强制硬盘同步,fsync 将阻塞直到写入硬盘完成后返回,保证了数据持久化。 + +Redis 默认的同步机制为`everysec`,此时能够兼顾性能和保证数据安全,在发生意外宕机的时,最多会丢失一秒的数据。 + +### 3.3 相关配置 + +想要使用 AOF 功能,需要配置 `appendonly `的值为`yes`,默认值为`no`。默认 AOF 的文件名为 `appendonly.aof`, 可以通过修改`appendfilename`的值进行修改,和 RDB 文件的保存位置一样,默认保存在 Redis 的工作目录下。 + +## 四、对比分析 + +### 4.1 优点与缺点 + +#### RDB 的优点 + +- RDB 使用一次性生成内存快照的方式, 产生的文件紧凑压缩比更高, 适用于备份和全量复制等场景。 +- RDB 文件通常比同一数据集的等效 AOF 文件小,所以使用 RDB 恢复数据远远快于 AOF 方式。 +- RDB 最大限度地提高了Redis的性能,因为 Redis 父进程只需要 fork 出一个子进程,它本生并不会执行磁盘 I/O 等操作。 + +#### RDB 的缺点 + +- RDB 方式没办法做到数据的实时持久化,假设每次持久化的时间间隔是5分钟,当在上一次持久化后3分钟后发生了服务宕机,则这三分钟内的数据会全部丢失。 +- fork 操作是一个重量级的操作,如果数据集很大,Fork 操作可能会非常耗时。 + +#### AOF 的优点 + ++ AOF 能够实现实时或秒级的持久化操作,能够保证数据的最少丢失。 ++ 如果突然宕机,日志以半写命令结束,可以使用 redis-check-aof 工具进行修复,从而保证数据最少丢失。 + +#### AOF 的缺点 + ++ AOF文件通常比同一数据集等效的 RDB 文件大。 ++ 根据选择的同步策略的不同,AOF 可能比 RDB 还慢。 + +### 4.2 使用建议 + +按照 Redis 官方的推荐,为保证的数据安全性,可以同时使用这两种持久化机制,在 Redis 官方的长期计划里面,未来可能会将 AOF 和 RDB 统一为单一持久性模型。需要注意的是,在这种情况下,当 Redis 重新启动时,Redis 将使用 AOF 文件重建数据集,因为它可以保证数据的最少丢失。 + + + + + diff --git a/notes/installation/MongoDB单机环境搭建.md b/notes/installation/MongoDB单机环境搭建.md new file mode 100644 index 0000000..6024960 --- /dev/null +++ b/notes/installation/MongoDB单机环境搭建.md @@ -0,0 +1,84 @@ +# MongoDB 单机版本环境搭建 + +## 一、下载并解压 + +下载地址为: https://www.mongodb.com/download-center/community ,选择所需版本的 MongoDB 后进行下载: + +![mongodb-version-select](D:\Full-Stack-Notes\pictures\mongodb-version-select.png) + +这里我下载的版本为 `4.0.10` , 安装环境为 `RHEL 7.0`,下载后进行解压: + +```shell + tar -zxvf mongodb-linux-x86_64-rhel70-4.0.10.tgz -C /usr/app +``` + +## 二、配置环境变量 + +配置环境变量: + +```shell +vi /etc/profile +``` + + + +```shell +export MONGODB_HOME=/usr/app/mongodb-linux-x86_64-rhel70-4.0.10/ +export PATH=${MONGODB_HOME}/bin:$PATH +``` + +使得配置的环境变量立即生效: + +```shell +source /etc/profile +``` + +## 三、修改配置 + +MongoDB 默认存放数据的目录为 `/var/lib/mongo` ,默认存放日志的目录为 `/var/log/mongodb`,采用 TGZ 安装包进行安装时,程序不会自动创建这两个目录,需要预先手动创建。同时由于 `/var/` 下只能存放临时文件,所以这里我们使用其他目录进行存储,命令如下: + +```shell +mkdir -p /home/mongodb/data +mkdir -p /home/mongodb/log +``` + +修改配置,采用 TGZ 安装包进行安装时,程序不会自动创建配置文件,需要手动创建: + +``` +vim /etc/mongod.conf +``` + +在配置文件中增加如下配置,这里的配置采用的是 YAML 的格式: + +```shell +systemLog: + destination: file + path: "/home/mongodb/log/mongod.log" + logAppend: true +storage: + dbPath: "/home/mongodb/data" +net: + port: 27017 + # 如果不修改绑定IP,默认只能在本机访问数据库服务 + bindIp: 0.0.0.0 +``` + +> MongoDB 的所有配置项可以参考其官方文档:[Configuration File Options](https://docs.mongodb.com/manual/reference/configuration-options/) + +## 四、启动服务 + +由于已经配置过环境变量,这里直接启动即可,命令如下: + +```shell +mongod -f /etc/mongod.conf +``` + +## 五、连接服务 + +这里直接使用 mongo shell 进行连接,mongo shell 默认就是连接到本地的 `27017` 端口,所以直接启动即可: + +```shell +mongo +``` + +成功进入交互式命令行则代表启动成功。 \ No newline at end of file diff --git a/pictures/mongodb-version-select.png b/pictures/mongodb-version-select.png new file mode 100644 index 0000000000000000000000000000000000000000..75f7820b4328d37c8a1b208de3332d034c3c7ec5 GIT binary patch literal 11785 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 ufTtn!Aq@W