第七周作业

[TOC]

一、postgresql架构与原理

1.1、体系架构概览

①PostgreSQL和MySQL相似,也采用典型的C/S模型。

②PostgreSQL体系结构分两部分

​ ——实例 instance

​ ——磁盘存储

③实例 instance 包括

——进程

——内存存储结构

image-20221102160659303

1.2、进程和内存结构

PostgreSQL是进程架构模型,MySQL是线程架构模型。

image-20221102160919783

1.2.1、进程

Postmaster 主进程

​ 它是整个数据库实例的主控制进程,负责启动和关闭该数据库实例。

​ 实际上,使用pg ctl来启动数据库时,pg_ctl也是通过运行postgres来启动数据库的,只是它做了一些包装,更容易启动数据库。

​ 它是第一个PostgreSQL进程,此主进程还会fork出其他子进程,并管理它们。

​ 当用户和PostgreSQL建立连接时,首先是和Postmaster进程建立连接。首先,客户端会发出身份验证的信息给Postmaster进程,Postmaster进程根据消息中的信息进行身份验证判断,如果验证通过,它会fork出一个会话子进程为这个连接服务。

​ 当某个服务进程出现错误的时候,Postmaster主进程会自动完成系统的恢复。恢复过程中会停掉所有的服务进程,然后进行数据库数据的一致性恢复,等恢复完成后,数据库又可以接受新的连接。

​ 验证功能是通过配置文件pg_hba.conf和用户验证模块来提供。

​ postmaster 程序是指向postgres的软链接

1
2
3
[root@ubuntu2004 ~]#ll /apps/pgsql/bin/postmaster 
lrwxrwxrwx 1 root root 8 Dec 28 01:19 /apps/pgsql/bin/postmaster ->
postgres*

BgWriter 后台写进程

​ 为了提高插入、删除和更新数据的性能,当往数据库中插入或者更新数据时,并不会马上把数据持久化到数据文件中,而是先写入Buffer中

​ 该辅助进程可以周期性的把内存中的脏数据刷新到磁盘中

WalWriter 预写式日志进程

​ WAL是write ahead log的缩写,WAL log旧版中称为xlog,相当于MySQL中Redo log

​ 预写式日志是在修改数据之前,必须把这些修改操作记录到磁盘中,这样后面更新实际数据时,就不需要实时的把数据持久化到文件中了。即使机器突然宕机或者数据库异常退出, 导致一部分内存中的脏数据没有及时的刷新到文件中,在数据库重启后,通过读取WAL日志,并把最后一部分WAL日志重新执行一遍,就能恢复到宕机时的状态了

​ WAL日志保存在pg_wal目录(早期版本为pg_xlog) 下。每个xlog 文件默认是16MB,为了满足恢复要求,在pg_wal目录下会产生多个WAL日志,这样就可保证在宕机后,未持久化的数据都可以通过WAL日志来恢复,那些不需要的WAL日志将会被自动覆盖

Checkpointer 检查点进程

​ 检查点(Checkpoints)是事务序列中的点,保证在该点之前的所有日志信息都更新到数据文件

中。

​ 在检查点时,所有脏数据页都冲刷到磁盘并且向日志文件中写入一条特殊的检查点记录。在发生崩溃的时候,恢复器就知道应该从日志中的哪个点(称做 redo 记录)开始做 REDO 操作,因为在该记录前的对数据文件的任何修改都已经在磁盘上了。在完成检查点处理之后,任何在redo记录之前写的日志段都不再需要,因此可以循环使用或者删除。在进行 WAL 归档的时候,这些日志在循环利用或者删除之前应该必须先归档保存

​ 检查点进程 (CKPT) 在特定时间自动执行一个检查点,通过向数据库写入进程 (BgWriter) 传递消息来启动检查点请求

AutoVacuum 自动清理进程

​ 执行delete操作时,旧的数据并不会立即被删除,在更新数据时,也不会在旧的数据上做更新,而是新生成一行数据。旧的数据只是被标识为删除状态,在没有并发的其他事务读到这些旧数据时,它们才会被清除掉

​ autovacuum lanucher 负责回收垃圾数据的master进程,如果开启了autovacuum的话,那么postmaster会fork这个进程

​ autovacuum worker 负责回收垃圾数据的worker进程,是lanucher进程fork出来的

PgStat 统计数据收集进程

​ 此进程主要做数据的统计收集工作

​ 收集的信息主要用于查询优化时的代价估算。统计的数据包括对一个表或索引进行的插入、删除、更新操作,磁盘块读写的次数以及行的读次数等。

​ 系统表pg_statistic中存储了PgStat收集的各类统计信息

PgArch 归档进程

​ 默认没有此进程,开启归档功能后才会启动archiver进程

​ WAL日志文件会被循环使用,也就是说WAL日志会被覆盖,利用PgArch进程会在覆盖前把WAL日志备份出来,类似于binlog,可用于备份功能

​ PostgreSQL 从8.X版本开始提供了PITR ( Point-In-Time-Recovery)技术,即就是在对数据厍进行过一次全量备份后,该技术将备份时间点后面的WAL日志通过归档进行备份,将来可以使用数据库的全量备份再加上后面产生的WAL 日志,即可把数据库向前恢复到全量备份后的任意一个时间点的状态

SysLogger 系统日志进程

​ 默认没有此进程,配置文件 postgresql.conf 设置参数logging_collect设置为“on”时,主进程才会启动SysLogger辅助进程

​ 它从Postmaster主进程、所有的服务进程以及其他辅助进程收集所有的stderr输出,并将这些输出写入到日志文件中

startup 启动进程

​ 用于数据库恢复的进程

Session 会话进程

​ 每一个用户发起连接后,一旦验证成功,postmaster进程就会fork—个新的子进程负责连接此

用户。

​ 通常表现为进程形式: postgres postgres [local] idle

案例: 查看进程

image-20221102161934614

1.2.2、内存结构

PostgreSQL的内存空间包括共享内存和本地内存两部分

共享内存

​ PostgreSQL启动后,会生成一块共享内存,共享内存主要用做数据块的缓冲区,以便提高读写性能。WAL日志缓冲区和CLOG(Commit log)缓冲区也存在于共享内存中。除此以外,一些全局信息也保存在共享内存中,如进程信息、锁的信息、全局统计信息等。

​ PostgreSQL 9.3之前的版本与Oracle数据库一样,都是使用“System V”类型的共享内存,但到PostgreSQL9.3之后,PostgreSQL使用mmap()方式共享内存,好处能使用较大的共享内存。

​ 可以通过配置postgresql.conf文件中shared_buffers 指定,默认128M,建议是内存的50%

本地内存

​ 后台服务进程除访问共享内存外,还会申请分配一些本地内存,以便暂存一些不需要全局存储的数据。

​ 都可以通过在配置postgresql.conf文件中指定

​ 这些内存缓冲区主要有以下几类:

​ temp_buffers :用于访问临时表的本地缓冲区,默认为8M

​ work_mem:内部排序操作和Hash表在使用临时磁盘文件之前使用的内存缓冲区,默认为4M

​ maintenance_work_mem:在维护性操作(比如 VACUUM、CREATE INDEX和ALTERTABLE ADD FOREIGN KEY 等)中使用的内存缓冲区,默认为64M

1.3、数据更新过程

image-20221102163110717

①先将数据库文件中的更改的数据加载至内存

②在内存更新数据

③将日志写入内存WAL的缓存区

④将日志提交,将日志写入操作系统 cache

⑤同步日志到磁盘

⑥后台写数据库的更新后的数据到操作系统 cache

⑦写完数据后,更新检查点checkpoint

⑧同步数据到磁盘

二、基于流复制完成postgresql的高可用

2.1、基础环境准备

1
2
3
#两个主机节点
10.0.0.184 Master
10.0.0.185 Standby

2.2、Master节点配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#创建复制的用户并授权
[postgres@Rocky ~]$psql
postgres=# create role repluser with replication login password '123456';

#修改pg_hba.conf进行授权
[postgres@Rocky ~]$vim /pgsql/data/pg_hba.conf
host replication repluser 10.0.0.0/24 md5

#修改配置(可选):
[postgres@Rocky ~]$vim /pgsql/data/postgresql.conf
archive_mode = on   #建议打开归档模式,防止长时间无法同步,WAL被覆盖造成数据丢失
archive_command = '[ ! -f /archive/%f ] && cp %p /archive/%f'
:wq
[root@Rocky ~]#mkdir /archive
[root@Rocky ~]#chown -R postgres. /archive

[postgres@Rocky ~]$pg_ctl restart

2.3、Standby节点配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#清空数据和归档
[postgres@Rocky ~]$pg_ctl stop
[postgres@Rocky ~]$rm -rf /pgsql/data/* #清空数据库
[postgres@Rocky ~]$rm -rf /archive/* #清空归档,归档最好开启,此目录需要自己创建
[postgres@Rocky ~]$rm -rf /pgsql/backup/* #清空以前的备份,如果没有则需要穿件备份目录

[root@Rocky ~]#mkdir /pgsql/backup
[root@Rocky ~]#chown postgres. /pgsql/backup
[root@Rocky ~]#mkdir /archive
[root@Rocky ~]#chown postgres. /archive

#备份主库数据到备库
[postgres@Rocky ~]$pg_basebackup -D /pgsql/backup/ -Ft -Pv -Urepluser -h 10.0.0.184 -p 5432 -R #-R:必须有 -Pv:是显示复制过程
[postgres@Rocky ~]$ls /pgsql/backup #查看数据已备份
backup_manifest base.tar pg_wal.tar

#还原备份的数据,实现初始的主从数据同步
[postgres@Rocky ~]$tar xf /pgsql/backup/base.tar -C /pgsql/data
[postgres@Rocky ~]$tar xf /pgsql/backup/pg_wal.tar -C /archive/
[postgres@Rocky ~]$ls /archive #查看归档日志已解压
000000010000000000000003
[postgres@Rocky ~]$ls /pgsql/data #查看数据已解压
backup_label pg_dynshmem pg_multixact pg_snapshots pg_tblspc pg_xact standby.signal base pg_hba.conf pg_notify pg_stat pg_twophase tablespace_map global pg_ident.conf pg_replslot pg_stat_tmp PG_VERSION postgresql.conf pg_commit_ts pg_logical pg_serial pg_subtrans pg_wal serverlog postgresql.auto.conf

#修改postgresql.conf文件
[postgres@Rocky ~]$vim /pgsql/data/postgresql.conf
primary_conninfo = 'host=10.0.0.184 port=5432 user=repluser password=123456'
restore_command = 'cp /archive/%f %p' #此项可不配置
:wq

[postgres@Rocky ~]$pg_ctl start

2.4、监控同步状态

2.4.1、查看主库状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[root@Rocky ~]#pg_controldata
pg_control version number: 1300
Catalog version number: 202107181
Database system identifier: 7160103462514775493
Database cluster state: in production #主库状态

postgres=# select pid,state,client_addr,sync_priority,sync_state from pg_stat_replication;
pid | state | client_addr | sync_priority | sync_state
------+-----------+-------------+---------------+------------
4499 | streaming | 10.0.0.185 | 0 | async
# 从服务器ip 异步(sync:同步)

#下面只在主节点查看同步模式,注意:如果无从节点连接,将无任何显示信息
postgres=# SELECT pg_current_wal_insert_lsn(),* from pg_stat_replication;
-[ RECORD 1 ]-------------+------------------------------
pg_current_wal_insert_lsn | 0/4000148 #当前的lsn号
pid | 4499
usesysid | 16384
usename | repluser
application_name | walreceiver
client_addr | 10.0.0.185
client_hostname |
client_port | 34426
backend_start | 2022-11-02 17:33:24.681961+08
backend_xmin |
state | streaming
sent_lsn | 0/4000148 #同步的lsn号,和上面一致,说明同步,有差表示有同步延迟
write_lsn | 0/4000148
flush_lsn | 0/4000148
replay_lsn | 0/4000148
write_lag |
flush_lag |
replay_lag |
sync_priority | 0
sync_state | async
reply_time | 2022-11-02 17:41:55.510802+08

#服务器查看数据库是否为备库,f表主库 t表示为备库
postgres=# select * from pg_is_in_recovery();
pg_is_in_recovery
-------------------
f

2.4.2、查看从库状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#从节点可以读
postgres=# select * from student;
id | name
----+--------------------------------
1 | zhang

#从节点不支持写
postgres=# insert into student(name)values('wang');
ERROR: cannot execute INSERT in a read-only transaction

[root@Rocky ~]#pg_controldata
pg_control version number: 1300
Catalog version number: 202107181
Database system identifier: 7160103462514775493
Database cluster state: in archive recovery #从库状态

2.5、切换主从

2.5.1、将从库切换为主库
1
2
3
4
5
6
7
8
9
10
11
12
[postgres@Rocky ~]$pg_ctl promote
waiting for server to promote.... done
server promoted

[postgres@Rocky ~]$pg_controldata
pg_control version number: 1300
Catalog version number: 202107181
Database system identifier: 7160103462514775493
Database cluster state: in production #现在是主库状态了

[postgres@Rocky ~]$pg_ctl restart

2.5.2、将原主库切换为从库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#清空数据和归档
[postgres@Rocky ~]$pg_ctl stop
[postgres@Rocky ~]$rm -rf /pgsql/data/*
[postgres@Rocky ~]$rm -rf /archive/*
[postgres@Rocky ~]$rm -rf /pgsql/backup/*

[root@Rocky ~]#mkdir /pgsql/backup
[root@Rocky ~]#chown postgres. /pgsql/backup

#备份主库数据到备库
[postgres@Rocky ~]$pg_basebackup -D /pgsql/backup/ -Ft -Pv -Urepluser -h 10.0.0.185 -p 5432 -R #-R:必须有 -Pv:是显示复制过程
[postgres@Rocky ~]$ls /pgsql/backup #查看数据已备份
backup_manifest base.tar pg_wal.tar

#还原备份的数据,实现初始的主从数据同步
[postgres@Rocky ~]$tar xf /pgsql/backup/base.tar -C /pgsql/data
[postgres@Rocky ~]$tar xf /pgsql/backup/pg_wal.tar -C /archive/

#修改postgresql.conf文件
[postgres@Rocky ~]$vim /pgsql/data/postgresql.conf
primary_conninfo = 'host=10.0.0.185 port=5432 user=repluser password=123456'
restore_command = 'cp /archive/%f %p' #此项可不配置
:wq

[postgres@Rocky ~]$pg_ctl start

#在原主库服务器查看状态
[postgres@Rocky ~]$pg_controldata
pg_control version number: 1300
Catalog version number: 202107181
Database system identifier: 7160103462514775493
Database cluster state: in archive recovery #现在已是从服务状态

postgres=# select * from pg_is_in_recovery();
pg_is_in_recovery
-------------------
t
(1 row)
2.5.3、验证同步状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#在新主服务器插入数据,看从服务器是否更新
#主服务器插入数据
postgres=# insert into student(name)values('li');
INSERT 0 1
postgres=# select * from student;
id | name
----+--------------------------------
1 | zhang
34 | li

#从服务器查看数据,已更新
postgres=# select * from student;
id | name
----+--------------------------------
1 | zhang
34 | li

三、实现postgresql的时间点还原

3.1、备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#在服务器端开启归档设置
[root@server ~]#su - postgres
[postgres@server ~]$vim /pgsql/data/postgresql.conf
archive_mode = on
archive_command = 'test ! -f /archive/%f &&cp %p /archive/%f'
:wq
[root@server ~]#mkdir /archive
[root@server ~]#chown postgres. /archive
[postgres@server ~]$pg_ctl restart

#在服务器端创建复制的用户并授权
[postgres@server ~]$psql
postgres=# create role repluser with replication login password '123456';
#修改pg_hba.conf进行授权
[postgres@server ~]$vim /pgsql/data/pg_hba.conf
host replication repluser 10.0.0.0/24 md5
:wq
[postgres@server ~]$pg_ctl restart

#在服务器端创建测试数据
[postgres@server ~]$psql
postgres=# create database test1; #创建test1数据库
postgres=# \c test1
test1=# create table student(id int,name char(30)); #创建student表
test1=# insert into student values(1,'zhang'); #在表中插入数据
test1=# insert into student values(2,'song');
test1=# insert into student values(3,'li');
test1=# insert into student values(4,'wang');

#在测试服务器上进行备份
[postgres@test ~]$vim /pgsql/data/postgresql.conf
archive_mode = on #开启归档
archive_command = 'test ! -f /archive/%f && cp %p /archive/%f'
:wq
[root@test ~]#mkdir /archive
[root@test ~]#chown postgres. /archive
[postgres@Rocky ~]$pg_ctl restart
[root@test ~]#mkdir /pgsql/backup
[root@test ~]#chown postgres. /pgsql/backup/
[root@test ~]#pg_basebackup -D /pgsql/backup/ -Ft -Pv -Urepluser -h 10.0.0.184 -p 5432 -R #备份到/pgsql/backup/

#在PG服务器上继续生成测试数据
test1=# insert into student values(5,'liu');
test1=# insert into student values(6,'han');

#模拟数据库删除
postgres=# drop database test1;

#发现故障,停止用户访问
#查看当前日志文件
postgres=# select pg_walfile_name(pg_current_wal_lsn());
pg_walfile_name
--------------------------
000000010000000000000004

#查看当前事务ID
postgres=# select txid_current();
txid_current
--------------
744

3.2、还原

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#在服务器上切换归档日志
postgres=# select pg_switch_wal();

#在测试机上还原,先停止服务
[postgres@test ~]$pg_ctl stop
#在测试机上将数据进行还原
[root@test ~]#rm -rf /pgsql/data/*
[root@test ~]#rm -rf /archive/*
[root@test ~]#tar xf /pgsql/backup/base.tar -C /pgsql/data
[root@test ~]#rsync -a 10.0.0.184:/archive/ /archive/
[root@test ~]#ls /archive
000000010000000000000001 000000010000000000000003 000000010000000000000003.00000028.backup
000000010000000000000002 000000010000000000000004

#查看故障点事务ID
[root@test ~]#pg_waldump /archive/000000010000000000000004
rmgr: Transaction len (rec/tot): 34/ 34, tx: 742, lsn: 0/04000290, prev 0/04000230, desc: COMMIT 2022-11-03 11:39:07.796583 CST

rmgr: Database len (rec/tot): 38/ 38, tx: 743, lsn: 0/04000880, prev 0/04000808, desc: DROP dir 1663/16385
#可以确认删库的事务id是743,所有恢复到742即可(恢复到2022-11-03 11:39:07.796583时间点也可以)

#修改配置文件postgresql.conf
[postgres@test ~]$vim /pgsql/data/postgresql.conf
restore_command = 'cp /archive/%f %p'
recovery_target_xid = '742'
:wq
#也可以通过下面方式指定还原至的位置
recovery_target_time = '2022-11-03 11:39:07'
recovery_target_lsn = '0/04000290'

[postgres@test ~]$pg_ctl start

[postgres@test ~]$psql
postgres=# \l #可以看到test1数据库已恢复
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
test1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
test1=# select * from student; #删库前的所有数据已恢复
id | name
----+--------------------------------
1 | zhang
2 | song
3 | li
4 | wang
5 | liu
6 | han

#当前无法写入
test1=# insert into student values(7,'sun');
2022-11-03 12:02:08.031 CST [35762] ERROR: cannot execute INSERT in a read-only transaction
2022-11-03 12:02:08.031 CST [35762] STATEMENT: insert into student values(7,'sun');
ERROR: cannot execute INSERT in a read-only transaction
#查看此时的状态
[root@test ~]#pg_controldata
pg_control version number: 1300
Catalog version number: 202107181
Database system identifier: 7160103462514775493
Database cluster state: in archive recovery #此时状态不是production

test1=# select pg_wal_replay_resume(); #执行此命令可恢复到写状态
test1=# insert into student values(7,'sun'); #可以添加数据了
INSERT 0 1

#查看此时的状态
[root@test ~]#pg_controldata
pg_control version number: 1300
Catalog version number: 202107181
Database system identifier: 7160103462514775493
Database cluster state: in production

四、规划高可用的LAMP,要求wordpress网站放在NFS共享存储上,并且用户可以正常发布博客,上传图片。尝试更新wordpress版本,测试网站仍可用

4.1、环境准备

1
2
3
4
5
6
7
8
9
10
11
共设6台主机
两台是web服务器,分别是:
LAP1 10.0.0.184
LAP2 10.0.0.185
一台是数据库服务器
mysql 10.0.0.186
两台是NFS服务器,分别是
NFS1(主服务器) 10.0.0.216
NFS2(备份服务器) 10.0.0.217
一台是DNS服务器
DNS 10.0.0.218

4.2、服务器配置

4.2.1、web服务器配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
安装LAP,需先安装以下包
[root@LAP1 ~]#yum -y install httpd php php-mysqlnd php-json
[root@LAP1 ~]#systemctl enable --now httpd #设置开机启动,并立即启动

#下载wordpress软件,官网https://cn.wordpress.org/download/
[root@LAP1 ~]#wget https://cn.wordpress.org/latest-zh_CN.tar.gz
[root@LAP1 ~]#ls #查看已下载完成
anaconda-ks.cfg latest-zh_CN.tar.gz
[root@LAP1 ~]#tar xf latest-zh_CN.tar.gz #解压到当前文件夹
[root@LAP1 ~]#ls #解压后是wordpress文件
anaconda-ks.cfg latest-zh_CN.tar.gz wordpress
[root@LAP1 ~]#mv wordpress/* /var/www/html
[root@LAP1 ~]#chown apache.apache /var/www/html -R #将html文件的权限授予apache

[root@LAP2 ~]#yum -y install httpd php php-mysqlnd php-json
[root@LAP2 ~]#systemctl enable --now httpd
[root@LAP2 ~]#wget https://cn.wordpress.org/latest-zh_CN.tar.gz
[root@LAP2 ~]#tar xf latest-zh_CN.tar.gz
[root@LAP2 ~]#ls
anaconda-ks.cfg latest-zh_CN.tar.gz wordpress
[root@LAP2 ~]#mv wordpress/* /var/www/html
[root@LAP2 ~]#chown apache.apache /var/www/html -R

#NFS服务器配置完成后,wep服务器需进行以下操作
[root@LAP1 html]#yum -y install nfs-utils
[root@LAP1 html]#showmount -e 10.0.0.216 #查看是否可以看到10.0.0.216的共享
Export list for 10.0.0.216:
/data/www *
[root@LAP1 ~]#cd /var/www/html/wp-content
[root@LAP1 wp-content]#mkdir uploads #创建文件夹
[root@LAP1 wp-content]#chown apache.apache uploads #更改所属用户和组
[root@LAP1 html]#vim /etc/fstab #永久挂载
10.0.0.216:/data/www /var/www/html/wp-content/uploads nfs _netdev 0 0
#挂载文件 挂载目录 协议 没有网络不挂载
:wq
[root@LAP1 wp-content]#mount -a #将/etc/fstab的所有内容重新加载

[root@LAP2 html]#yum -y install nfs-utils
[root@LAP2 html]#showmount -e 10.0.0.216 #查看是否可以看到10.0.0.216的共享
Export list for 10.0.0.216:
/data/www * #可以看到
[root@LAP2 ~]#cd /var/www/html/wp-content
[root@LAP2 wp-content]#mkdir uploads #创建文件夹
[root@LAP2 wp-content]#chown apache.apache uploads #更改所属用户和组
[root@LAP2 html]#vim /etc/fstab #永久挂载
10.0.0.216:/data/www /var/www/html/wp-content/uploads nfs _netdev 0 0
:wq
[root@LAP2 wp-content]#mount -a #将/etc/fstab的所有内容重新加载
4.2.2、NFS服务器配置
4.2.2.1、NFS1基于存储wordpress图片设置

如果不设置NFS服务器,那wordpress里面的图片只储存在web服务器上(/var/www/html/wp-content/uploads),如果服务器坏了,则图片会丢失(其他数据不会丢失,其他数据存储在mysql数据库里)

1
2
3
4
5
6
7
8
9
10
[root@nfs1 ~]#mkdir -p /data/www                      #此文件夹是存放共享图片的
[root@nfs1 ~]#useradd -u 666 www #创建id号为666的用户www,此账号用于后面的压榨账号
[root@nfs1 ~]#vim /etc/exports
/data/www *(rw,all_squash,anonuid=666,anonuid=666)
# 共享地址 读写权限,压榨所有用户,指定压榨后映射的用户uid为666的用户
:wq
#在往共享文件里存放图片,需要给权限
[root@nfs1 ~]#chown www.www /data/www #将文件给与www用户权限
[root@nfs1 ~]#yum -y install nfs-utils #安装nfs
[root@nfs1 ~]#systemctl enable --now nfs-server #设置开机启动,并立即启动
4.2.2.2、基于主NFS服务器和备份NFS服务器进行配置

rsync 常用于做为 linux系统下的数据镜像备份工具,实现远程同步,支持本地复制,或者与其他SSH、rsync主机同步数据,支持增量备份,配合任务计划,rsync能实现定时或间隔同步,配合inotify或sersync,可以实现触发式的实时数据同步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
[root@nfs2 ~]#yum -y install rsync       #用于在备份NFS服务器上开启远程监听端口873(centos8安装rsync-daemon)
[root@nfs2 ~]#systemctl enable --now rsyncd.service
[root@nfs2 ~]#ss -ntl #查看873端口已开启
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 5 *:873 *:*
[root@nfs2 ~]#vim /etc/rsyncd.conf
uid = root #提定以哪个用户来访问共享目录,将之指定为生成的文件所有者,默认为nobody
gid = root #默认为nobody,Ubuntu中为nogroup
max connections = 0
ignore errors
exclude = lost+found/
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
reverse lookup = no

[backup] #每个模块名对应一个不同的path目录,如果同名后面模块生效
path = /data/backup/ #备份服务器共享的文件夹
comment = backup dir
read only = no #默认是yes,即只读
auth users = rsyncuser #默认anonymous可以访问rsync服务器,指定访问账号rsyncuser
secrets file = /etc/rsync.pas #账号密码存放路径
:wq
[root@nfs2 ~]#mkdir -p /data/backup #创建共享文件夹

#此时在主NFS服务器上就可以看到备份服务器的共享文件了
[root@nfs1 ~]#yum -y install rsync
[root@nfs1 ~]#systemctl enable --now rsyncd.service
[root@nfs1 ~]#rsync rsync://10.0.0.217
backup backup dir

#服务器端生成验证文件
[root@nfs2 ~]#echo "rsyncuser:magedu" > /etc/rsync.pas
# 用户:密码
[root@nfs2 ~]#chmod 600 /etc/rsync.pas #指定只允许root用户读写
#此时主NFS服务器端想连接备份服务器,需要输入密码
[root@nfs1 ~]#echo "magedu" > /etc/rsync.pas #直接创建个密码文件
[root@nfs1 ~]#chmod 600 /etc/rsync.pas #指定只允许root用户访问


#在数据服务器上下载sersync,并拷贝至相应的目录,
[root@nfs1 ~]#tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz -C /opt/
#将包解压到/opt/目录下
[root@nfs1 ~]#cd /opt
[root@nfs1 opt]#ls
GNU-Linux-x86
[root@nfs1 opt]#cd GNU-Linux-x86/
[root@nfs1 GNU-Linux-x86]#ls
confxml.xml sersync2
#直接修改confxml.xml文件,后者将本地的直接拉进来
[root@nfs1 GNU-Linux-x86]#mv confxml.xml{,.bak}
[root@nfs1 GNU-Linux-x86]#ls
confxml.xml confxml.xml.bak sersync2
[root@nfs1 GNU-Linux-x86]#./sersync2 -h 查看sersync2的帮助
set the system param
execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
parse the command param
_______________________________________________________
参数-d:启用守护进程模式
参数-r:在监控前,将监控目录与远程主机用rsync命令推送一遍
c参数-n: 指定开启守护线程的数量,默认为10个
参数-o:指定配置文件,默认使用confxml.xml文件
参数-m:单独启用其他模块,使用 -m refreshCDN 开启刷新CDN模块
参数-m:单独启用其他模块,使用 -m socket 开启socket模块
参数-m:单独启用其他模块,使用 -m http 开启http模块
不加-m参数,则默认执行同步程序
________________________________________________________________
[root@nfs1 GNU-Linux-x86]#./sersync2 -dro /opt/GNU-Linux-x86/confxml.xml
#d是后台执行 r是先同步一遍 o是指的文件路径

#为了实现开机启动此服务,可以将此命令写入/etc/rc.local,实现开机启动
[root@nfs1 ~]#vim /etc/rc.local
/opt/GNU-Linux-x86/sersync2 -dro /opt/GNU-Linux-x86/confxml.xml
:wq
[root@nfs1 ~]#chmod +x /etc/rc.local
4.2.3、DNS配置

设置DNS,主要是为了将ip地址解析为网址

4.2.3.1、DNS服务器配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[root@dns ~]#yum -y install bind bind-utils      #安装DNS
[root@dns ~]#vim /etc/named.conf #修改配置文件
listen-on port 53 { localhost; }; #将172.0.0.1改为localhost,localhost表示本机所有IP;或者将此行用//注释掉;或者在127.0.0.1;后面添加其他允许访问的IP地址
allow-query { any; }; #将localhost改为any,localhost说的是只允许本机访问,需让其他机器也可以访问,方法有三种:①加//将此行注释,所有机器都可以访问②将localhost更改为any,所有机器都允许③在localhost;添加允许访问的IP地址
:wq
[root@dns ~]#vim /etc/named.rfc1912.zones #修改配置文件,增加magedu.org
zone "jiagoukecheng.org" IN {
type master;
file "jiagoukecheng.org.zone";
};
:wq
[root@dns named]#named-checkconf #检查配置文件是否有语法错误
[root@dns ~]#cd /var/named
[root@dns named]#vim jiagoukecheng.org.zone #创建编辑magedu.org所属文件数据库
$TTL 1D
@ IN SOA master admin ( 0 1D 1H 1W 3H )
NS master
master A 10.0.0.218
www A 10.0.0.185
www A 10.0.0.184
:wq
[root@dns named]#chmod 640 jiagoukecheng.org.zone #修改文件权限
[root@dns named]#chgrp named jiagoukecheng.org.zone #修改所属组
[root@dns named]#ll
total 20
drwxrwx--- 2 named named 6 Oct 13 2020 data
drwxrwx--- 2 named named 6 Oct 13 2020 dynamic
-rw-r----- 1 root named 225 Nov 5 16:02 magedu.org.zone
-rw-r----- 1 root named 2253 Apr 5 2018 named.ca
-rw-r----- 1 root named 152 Dec 15 2009 named.empty
-rw-r----- 1 root named 152 Jun 21 2007 named.localhost
-rw-r----- 1 root named 168 Dec 15 2009 named.loopback
drwxrwx--- 2 named named 6 Oct 13 2020 slaves
[root@dns named]#named-checkzone jiagoukecheng.org /var/named/jiagoukecheng.org.zone #检查是否有语法错误
zone magedu.org/IN: loaded serial 0
OK #没有错误
[root@dns named]#systemctl enable --now named #将DNS设为开机启动,并立即启动
4.2.3.2、本地DNS配置

将本地的DNS指向10.0.0.218

image-20221105162739622

4.2.4、mysql服务器配置
1
2
3
4
5
6
[root@mysql ~]#yum -y install mysql-server
[root@mysql ~]#systemctl enable --now mysqld
[root@mysql ~]#mysql
mysql> create user wordpress@'10.0.0.%' identified by '123456'; #创建账号密码
mysql> create database wordpress; #创建存放wordpress数据的数据库
mysql> grant all on wordpress.* to wordpress@'10.0.0.%'; #授权

4.3、登录wordpress

注意:网站创建完成后,登录前台网址是:www.jiagoukecheng.org

​ 登录后台网址是:www.jiagoukecheng.org/wp-admin

①浏览器输入网址:www.jiagoukecheng.org

image-20221105171422005

②连接数据库

image-20221105171532771

③运行安装程序,设置网站的用户名和密码

image-20221105171914241

④登录网站

image-20221105172032598

image-20221105172059569

4.4、编写文章,并查看

①写文章插入图片

image-20221105183302080

②直接网址查看

image-20221105183351587

③web服务器查看存储位置

image-20221105183552699

④nfs服务器查看是否存储

image-20221105183536464

⑤查看NFS备份服务器是否共享

image-20221105205416647

五、redis数据类型有哪些

共有5中类型:字符串string、列表list、集合set、有序集合sorted set、哈希hash

5.1、字符串string

字符串是一种最基本的Redis值类型。Redis字符串是二进制安全的,这意味着一个Redis字符串能包含任意类型的数据,例如: 一张JPEG格式的图片或者一个序列化的Ruby对象。一个字符串类型的值最多能存储512M字节的内容。Redis 中所有 key 都是字符串类型的。此数据类型最为常用

image-20221107101739910

利用INCR命令簇(INCR, DECR, INCRBY,DECRBY)来把字符串当作原子计数器使用。

5.2、列表list

①Redis列表就是简单的字符串数组,按照插入顺序排序. 支持双向读写,可以添加一个元素到列表的头部(左边)或者尾部(右边),一个列表最多可以包含2^32-1=4294967295个元素,每个列表元素有下标来标识,下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,元素值可以重复,常用于存入日志等场景,此数据类型比较常用

②列表特点:有序、可重复、左右都可以操作

image-20221107102111856

5.3、集合set

①Set 是一个无序的字符串合集,同一个集合中的每个元素是唯一无重复的,支持在两个不同的集合中对数据进行逻辑处理,常用于取交集,并集,统计等场景,例如: 实现共同的朋友

②集合特点:无序、无重复、集合间操作

image-20221107102353593

5.4、有序集合sorted set

①Redis有序集合和Redis集合类似,是不包含相同字符串的合集。它们的差别是,每个有序集合的成员都关联着一个双精度浮点型的评分,这个评分用于把有序集合中的成员按最低分到最高分排序。有序集合的成员不能重复,但评分可以重复,一个有序集合中最多的成员数为 2^32 - 1=4294967295个,经常用于排行榜的场景

②有序集合特点:有序、无重复元素、每个元素是由score和value组成、score 可以重复、value 不可以重复

image-20221107102549480

5.5、哈希hash

①hash 即字典, 用于保存字符串字段field和字符串值value之间的映射,即key/value做为数据部分,hash特别适合用于存储对象场景。一个hash最多可以包含2^32-1 个key/value键值对

②哈希特点:无序、k/v 对、适用于存放相关的数据

image-20221107102749619

六、redis RDB和AOF比较

6.1、RDB的优缺点

6.1.1、RDB的优点

①RDB快照只保存某个时间点的数据,恢复的时候直接加载到内存即可,不用做其他处理,这种文件适合用于做灾备处理.可以通过自定义时间点执行redis指令bgsave或者save保存快照,实现多个版本的备份。

比如: 可以在最近的24小时内,每小时备份一次RDB文件,并且在每个月的每一天,也备份一个RDB文件。这样的话,即使遇上问题,也可以随时将数据集还原到指定的不同的版本。

②RDB在大数据集时恢复的速度比AOF方式要快

6.1.2、RDB的缺点

①不能实时保存数据,可能会丢失自上一次执行RDB备份到当前的内存数据

如果需要尽量避免在服务器故障时丢失数据,那么RDB并不适合。虽然Redis允许设置不同的保存点(save point)来控制保存RDB文件的频率,但是,因为RDB文件需要保存整个数据集的状态,所以它可能并不是一个非常快速的操作。因此一般会超过5分钟以上才保存一次RDB文件。在这种情况下,一旦发生故障停机,就可能会丢失较长时间的数据。

②在数据集比较庞大时,fork()子进程可能会非常耗时,造成服务器在一定时间内停止处理客户端请求,如果数据集非常巨大,并且CPU时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒或更久。另外子进程完成生成RDB文件的时间也会花更长时间

6.2、AOF的优缺点

6.2.1、AOF的优点

①数据安全性相对较高,根据所使用的fsync策略(fsync是同步内存中redis所有已经修改的文件到存储设备),默认是appendfsync everysec,即每秒执行一次 fsync,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync会在后台线程执行,所以主线程可以继续努力地处理命令请求)

②由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中不需要seek, 即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,可以通过 redis-check-aof 工具来解决数据一致性的问题

③Redis可以在 AOF文件体积变得过大时,自动地在后台对AOF进行重写,重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的,因为Redis在创建新 AOF文件的过程中,append模式不断的将修改数据追加到现有的 AOF文件里面,即使重写过程中发生停机,现有的 AOF文件也不会丢失。而一旦新AOF文件创建完毕,Redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操作。

④AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,也可以通过该文件完成数据的重建

AOF文件有序地保存了对数据库执行的所有写入操作,这些写入操作以Redis协议的格式保存,因此 AOF文件的内容非常容易被人读懂,对文件进行分析(parse)也很轻松。导出(export)AOF文件也非常简单:举个例子,如果不小心执行了FLUSHALL.命令,但只要AOF文件未被重写,那么只要停止服务器,移除 AOF文件末尾的FLUSHAL命令,并重启Redis ,就可以将数据集恢复到FLUSHALL执行之前的状态。

6.2.2、AOF的缺点

①即使有些操作是重复的也会全部记录,AOF 的文件大小一般要大于 RDB 格式的文件

②AOF 在恢复大数据集时的速度比 RDB 的恢复速度要慢

③如果 fsync 策略是appendfsync no, AOF保存到磁盘的速度甚至会可能会慢于RDB

④bug 出现的可能性更多

6.3、RDB和AOF的选择

①如果主要充当缓存功能,或者可以承受较长时间,比如数分钟数据的丢失, 通常生产环境一般只需启用RDB

即可,此也是默认值

②如果一点数据都不能丢失,可以选择同时开启RDB和AOF

③一般不建议只开启AOF

七、redis配置文件详解

resdis.conf文件内容的解释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
bind 0.0.0.0 #指定监听地址,支持用空格隔开的多个监听IP

protected-mode yes #redis3.2之后加入的新特性,在没有设置bind IP和密码的时候,redis只允许访问127.0.0.1:6379,可以远程连接,但当访问将提示警告信息并拒绝远程访问

port 6379 #监听端口,默认6379/tcp

tcp-backlog 511 #三次握手的时候server端收到client ack确认号之后的队列值,即全连接队列长度

timeout 0 #客户端和Redis服务端的连接超时时间,默认是0,表示永不超时

tcp-keepalive 300 #tcp 会话保持时间300s

daemonize no #默认no,即直接运行redis-server程序时,不作为守护进程运行,而是以前台方式运行,如果想在后台运行需改成yes,当redis作为守护进程运行的时候,它会写一个 pid 到/var/run/redis.pid 文件

supervised no #和OS相关参数,可设置通过upstart和systemd管理Redis守护进程,centos7后都使用systemd

pidfile /var/run/redis_6379.pid #pid文件路径,可以修改为/apps/redis/run/redis_6379.pid

loglevel notice #日志级别

logfile "/path/redis.log" #日志路径,示例:logfile "/apps/redis/log/redis_6379.log"

databases 16 #设置数据库数量,默认:0-15,共16个库

always-show-logo yes #在启动redis 时是否显示或在日志中记录记录redis的logo

save 900 1 #在900秒内有1个key内容发生更改,就执行快照机制
save 300 10 #在300秒内有10个key内容发生更改,就执行快照机制
save 60 10000  #60秒内如果有10000个key以上的变化,就自动快照备份

stop-writes-on-bgsave-error yes #默认为yes时,可能会因空间满等原因快照无法保存出错时,会禁止redis写入操作,生产建议为no
#此项只针对配置文件中的自动save有效

rdbcompression yes #持久化到RDB文件时,是否压缩,"yes"为压缩,"no"则反之

rdbchecksum yes #是否对备份文件开启RC64校验,默认是开启

dbfilename dump.rdb #快照文件名

dir ./ #快照文件保存路径,示例:dir "/apps/redis/data"

#主从复制相关
# replicaof <masterip> <masterport> #指定复制的master主机地址和端口,5.0版之前的指令为
slaveof
# masterauth <master-password> #指定复制的master主机的密码

replica-serve-stale-data yes #当从库同主库失去连接或者复制正在进行,从机库有两种运行方式:
1、设置为yes(默认设置),从库会继续响应客户端的读请求,此为建议值
2、设置为no,除去特定命令外的任何请求都会返回一个错误"SYNC with master in progress"

replica-read-only yes #是否设置从库只读,建议值为yes,否则主库同步从库时可能会覆盖数据,造成数据丢失

repl-diskless-sync no #是否使用socket方式复制数据(无盘同步),新slave第一次连接master时需要做数据的全量同步,redis server就要从内存dump出新的RDB文件,然后从master传到slave,有两种方式把RDB文件传输给客户端:
1、基于硬盘(disk-backed):为no时,master创建一个新进程dump生成RDB磁盘文件,RDB完成之后由
父进程(即主进程)将RDB文件发送给slaves,此为默认值
2、基于socket(diskless):master创建一个新进程直接dump RDB至slave的网络socket,不经过主
进程和硬盘
#推荐使用基于硬盘(为no),是因为RDB文件创建后,可以同时传输给更多的slave,但是基于socket(为yes), 新slave连接到master之后得逐个同步数据。只有当磁盘I/O较慢且网络较快时,可用diskless(yes),否则一般建议使用磁盘(no)

repl-diskless-sync-delay 5 #diskless时复制的服务器等待的延迟时间,设置0为关闭,在延迟时间内到达的客户端,会一起通过diskless方式同步数据,但是一旦复制开始,master节点不会再接收新slave的复制请求,直到下一次同步开始才再接收新请求。即无法为延迟时间后到达的新副本提供服务,新副本将排队等待下一次RDB传输,因此服务器会等待一段时间才能让更多副本到达。推荐值:30-60

repl-ping-replica-period 10 #slave根据master指定的时间进行周期性的PING master,用于监测master状态,默认10s

repl-timeout 60 #复制连接的超时时间,需要大于repl-ping-slave-period,否则会经常报超时

repl-disable-tcp-nodelay no #是否在slave套接字发送SYNC之后禁用 TCP_NODELAY,如果选择"yes",Redis将合并多个报文为一个大的报文,从而使用更少数量的包向slaves发送数据,但是将使数据传输到slave上有延迟,Linux内核的默认配置会达到40毫秒,如果 "no" ,数据传输到slave的延迟将会减少,但要使用更多的带宽

repl-backlog-size 512mb #复制缓冲区内存大小,当slave断开连接一段时间后,该缓冲区会累积复制副本数据,因此当slave 重新连接时,通常不需要完全重新同步,只需传递在副本中的断开连接后没有同步的部分数据即可。只有在至少有一个slave连接之后才分配此内存空间,建议建立主从时此值要调大一些或在低峰期配置,否则会导致同步到slave失败

repl-backlog-ttl 3600 #多长时间内master没有slave连接,就清空backlog缓冲区

replica-priority 100 #当master不可用,哨兵Sentinel会根据slave的优先级选举一个master,此值最低的slave会优先当选master,而配置成0,永远不会被选举,一般多个slave都设为一样的值,让其自动选择

#min-replicas-to-write 3 #至少有3个可连接的slave,mater才接受写操作
#min-replicas-max-lag 10 #和上面至少3个slave的ping延迟不能超过10秒,否则master也将停止写操作

requirepass foobared #设置redis连接密码,之后需要AUTH pass,如果有特殊符号,用" "引起来,生产建议设置

rename-command #重命名一些高危命令,示例:rename-command FLUSHALL "" 禁用命令
  #示例: rename-command del magedu
 
maxclients 10000 #Redis最大连接客户端

maxmemory <bytes> #redis使用的最大内存,单位为bytes字节,0为不限制,建议设为物理内存一半,8G内存的计算方式8(G)*1024(MB)1024(KB)*1024(Kbyte),需要注意的是缓冲区是不计算在maxmemory内,生产中如果不设置此项,可能会导致OOM

#maxmemory-policy noeviction 此为默认值
# MAXMEMORY POLICY:当达到最大内存时,Redis 将如何选择要删除的内容。您可以从以下行为中选择一种:
#
# volatile-lru -> Evict 使用近似 LRU,只有设置了过期时间的键。
# allkeys-lru -> 使用近似 LRU 驱逐任何键。
# volatile-lfu -> 使用近似 LFU 驱逐,只有设置了过期时间的键。
# allkeys-lfu -> 使用近似 LFU 驱逐任何键。
# volatile-random -> 删除设置了过期时间的随机密钥。
# allkeys-random -> 删除一个随机密钥,任何密钥。
# volatile-ttl -> 删除过期时间最近的key(次TTL)
# noeviction -> 不要驱逐任何东西,只是在写操作时返回一个错误。
#
# LRU 表示最近最少使用
# LFU 表示最不常用
#
# LRU、LFU 和 volatile-ttl 都是使用近似随机算法实现的。
#
# 注意:使用上述任何一种策略,当没有合适的键用于驱逐时,Redis 将在需要更多内存的写操作时返回错误。这些通常是创建新密钥、添加数据或修改现有密钥的命令。一些示例是:SET、INCR、HSET、LPUSH、SUNIONSTORE、SORT(由于 STORE 参数)和 EXEC(如果事务包括任何需要内存的命令)。

#MAXMEMORY POLICY:当达到最大内存时,Redis 将如何选择要删除的内容。可以从下面行为中进行选择:
# volatile-lru -> 在具有过期集的键中使用近似 LRU 驱逐。
# allkeys-lru -> 使用近似 LRU 驱逐任何键。
# volatile-lfu -> 在具有过期集的键中使用近似 LFU 驱逐。
# allkeys-lfu -> 使用近似 LFU 驱逐任何键。
# volatile-random -> 从具有过期设置的密钥中删除一个随机密钥。
# allkeys-random -> 删除一个随机密钥,任何密钥。
# volatile-ttl -> 删除过期时间最近的key(次TTL)
# noeviction -> 不要驱逐任何东西,只是在写操作时返回一个错误。
#
# LRU 表示最近最少使用
# LFU 表示最不常用
#
# LRU、LFU 和 volatile-ttl 均使用近似实现随机算法。
#
# 注意:使用上述任何一种策略,Redis 都会在写入时返回错误操作,当没有合适的键用于驱逐时。

appendonly no #是否开启AOF日志记录,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了,但是redis如果中途宕机,会导致可能有几分钟的数据丢失(取决于dump数据的间隔时间),根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。默认不启用此功能

appendfilename "appendonly.aof" #文本文件AOF的文件名,存放在dir指令指定的目录中

appendfsync everysec #aof持久化策略的配置
#no表示由操作系统保证数据同步到磁盘,Linux的默认fsync策略是30秒,最多会丢失30s的数据
#always表示每次写入都执行fsync,以保证数据同步到磁盘,安全性高,性能较差
#everysec表示每秒执行一次fsync,可能会导致丢失这1s数据,此为默认值,也生产建议值

#同时在执行bgrewriteaof操作和主进程写aof文件的操作,两者都会操作磁盘,而bgrewriteaof往往会涉及大量磁盘操作,这样就会造成主进程在写aof文件的时候出现阻塞的情形,以下参数实现控制
no-appendfsync-on-rewrite no #在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略,主要考虑磁盘IO开支和请求阻塞时间。
#默认为no,表示"不暂缓",新的aof记录仍然会被立即同步到磁盘,是最安全的方式,不会丢失数据,但是要忍受阻塞的问题
#为yes,相当于将appendfsync设置为no,这说明并没有执行磁盘操作,只是写入了缓冲区,因此这样并不会造成阻塞(因为没有竞争磁盘),但是如果这个时候redis挂掉,就会丢失数据。丢失多少数据呢?Linux的默认fsync策略是30秒,最多会丢失30s的数据,但由于yes性能较好而且会避免出现阻塞因此比较推荐

#rewrite 即对aof文件进行整理,将空闲空间回收,从而可以减少恢复数据时间

auto-aof-rewrite-percentage 100 #当Aof log增长超过指定百分比例时,重写AOF文件,设置为0表示不自动重写Aof日志,重写是为了使aof体积保持最小,但是还可以确保保存最完整的数据

auto-aof-rewrite-min-size 64mb #触发aof rewrite的最小文件大小

aof-load-truncated yes #是否加载由于某些原因导致的末尾异常的AOF文件(主进程被kill/断电等),建议yes

aof-use-rdb-preamble no #redis4.0新增RDB-AOF混合持久化格式,在开启了这个功能之后,AOF重写产生的文件将同时包含RDB格式的内容和AOF格式的内容,其中RDB格式的内容用于记录已有的数据,而AOF格式的内容则用于记录最近发生了变化的数据,这样Redis就可以同时兼有RDB持久化和AOF持久化的优点(既能够快速地生成重写文件,也能够在出现问题时,快速地载入数据),默认为no,即不启用此功能

lua-time-limit 5000 #lua脚本的最大执行时间,单位为毫秒

cluster-enabled yes #是否开启集群模式,默认不开启,即单机模式

cluster-config-file nodes-6379.conf #由node节点自动生成的集群配置文件名称

cluster-node-timeout 15000 #集群中node节点连接超时时间,单位ms,超过此时间,会踢出集群

cluster-replica-validity-factor 10 #单位为次,在执行故障转移的时候可能有些节点和master断开一段时间导致数据比较旧,这些节点就不适用于选举为master,超过这个时间的就不会被进行故障转移,不能当选master,计算公式:(node-timeout * replica-validity-factor) + repl-pingreplica-period

cluster-migration-barrier 1 #集群迁移屏障,一个主节点至少拥有1个正常工作的从节点,即如果主节点的slave节点故障后会将多余的从节点分配到当前主节点成为其新的从节点。

cluster-require-full-coverage yes #集群请求槽位全部覆盖,如果一个主库宕机且没有备库就会出现集群槽位不全,那么yes时redis集群槽位验证不全,就不再对外提供服务(对key赋值时,会出现CLUSTERDOWN The cluster is down的提示,cluster_state:fail,但ping 仍PONG),而no则可以继续使用,但是会出现查询数据查不到的情况(因为有数据丢失)。生产建议为no

cluster-replica-no-failover no #如果为yes,此选项阻止在主服务器发生故障时尝试对其主服务器进行故障转移。 但是,主服务器仍然可以执行手动强制故障转移,一般为no

#Slow log 是 Redis 用来记录超过指定执行时间的日志系统,执行时间不包括与客户端交谈,发送回复等I/O操作,而是实际执行命令所需的时间(在该阶段线程被阻塞并且不能同时为其它请求提供服务),由于slow log 保存在内存里面,读写速度非常快,因此可放心地使用,不必担心因为开启 slow log 而影响Redis 的速度

slowlog-log-slower-than 10000 #以微秒为单位的慢日志记录,为负数会禁用慢日志,为0会记录每个命令操作。默认值为10ms,一般一条命令执行都在微秒级,生产建议设为1ms-10ms之间

slowlog-max-len 128 #最多记录多少条慢日志的保存队列长度,达到此长度后,记录新命令会将最旧的命令从命令队列中删除,以此滚动删除,即,先进先出,队列固定长度,默认128,值偏小,生产建议设为1000以上

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!