目录
数据库类型
关系型数据库
非关系型数据库
关系型数据库和非关系型数据库区别
Redis数据库
Redis的优点
Redis速度快的原因
Redis安装部署
1、环境准备
2、修改内核参数
3、安装redis
4、redis启动准备
5、配置环境变量和修改redis配置
6、定义systemd服务管理脚本
Redis命令工具
redis-cli 命令行工具
redis-benchmark 测试工具
Redis的数据类型
1、字符串(string)类型
2、列表(list)类型
3、哈希(hash)类型
4、无序集合(set)
5、有序集合(sorted set / zset)
通用命令
Redis持久化
RDB持久化
1、RDB持久化触发条件
2、RDB执行流程
AOF持久化
1. 开启AOF
2. 执行流程
RDB与AOF的区别
RDB持久化
AOF持久化
Redis优化
关系型数据库是一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一般面向于记录。
SQL 语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型数据库中数据的检索和操作。
主流的关系型数据库包括 Oracle、MySQL、SQL Server、Microsoft Access、PostgreSQL、DB2 等。
以上数据库在使用的时候必须先建库建表设计表结构,然后存储数据的时候按表结构去存,如果数据与表结构不匹配就会存储失败。
NoSQL(NoSQL = Not Only SQL ),意思是“不仅仅是 SQL”,是非关系型数据库的总称。
除了主流的关系型数据库外的数据库,都认为是非关系型。
不需要预先建库建表定义数据存储表结构,每条记录可以有不同的数据类型和字段个数(比如微信群聊里的文字、图片、视频、音乐等)。
主流的 NoSQL 数据库有 Redis、MongBD、Hbase、Memcached、ElasticSearch、TSDB 等。
SQL | NoSQL | |
存储结构 | 二维表格结构 | 不固定的,键值对、文档、索引、图形结构、时间序列等 |
扩展方式 | 纵向扩展(提升硬件性能) | 横向扩展(增加服务器节点数量) |
事务支持 | 基于ACID原则,事务控制更稳定,细粒度更高 | 基于BASE原则,稳定性和细粒度控制方面不如SQL |
典型代表 | MySQL MariaDB Oracle SQL-Server PostgreSQL | Redis Memcached MongDB ElasticSearch Prometheus |
Redis(远程字典服务器) 是一个开源的、使用 C 语言编写的 NoSQL 数据库。
Redis 基于内存运行并支持持久化,采用key-value(键值对)的存储形式,是目前分布式架构中不可或缺的一环。
Redis服务器程序是单进程模型,也就是在一台服务器上可以同时启动多个Redis进程,Redis的实际处理速度则是完全依靠于主进程的执行效率。若在服务器上只运行一个Redis进程,当多个客户端同时访问时,服务器的处理能力是会有一定程度的下降;若在同一台服务器上开启多个Redis进程,Redis在提高并发处理能力的同时会给服务器的CPU造成很大压力。即:在实际生产环境中,需要根据实际的需求来决定开启多少个Redis进程。若对高并发要求更高一些,可能会考虑在同一台服务器上开启多个进程。若CPU资源比较紧张,采用单进程即可。
(1)具有极高的数据读写速度:数据读取的速度最高可达到 110000 次/s,数据写入速度最高可达到 81000 次/s。
(2)支持丰富的数据类型:支持 key-value、Strings、Lists、Hashes、Sets 及 Sorted Sets 等数据类型操作。
(3)支持数据的持久化:可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
(4)原子性:Redis 所有操作都是原子性的。
(5)支持数据备份:即 master-salve 模式的数据备份。
(1)redis是基于内存运行的,数据操作都是内存中完成的
(2)数据读写采用单线程模式,避免了多线程切换的CPU性能消耗,同时也不用考虑锁的问题
(3)采用IO多路复用模型,可以使线程处理更多的网络连接请求,提高并发能力
systemctl stop firewalld #关闭防火墙
systemctl disable firewalld #关闭防火墙开机自启
setenforce 0 #关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config #修改selinu的配置文件,设置永久关闭yum install -y gcc gcc-c++ make #安装依赖环境
vim /etc/sysctl.conf
vm.overcommit_memory = 1
net.core.somaxconn = 2048
sysctl -p
cd /opt
tar xf redis-7.0.13.tar.gz
cd redis-7.0.13/
make
make PREFIX=/usr/local/redis install
mkdir /usr/local/redis/{conf,log,data,pid}
cp /opt/redis-7.0.13/redis.conf /usr/local/redis/conf/
vim /etc/profile
PATH=$PATH:/usr/local/redis/bin #增加一行source /etc/profile
vim /usr/local/redis/conf/redis.conf---87行 127.0.0.1后面换成自己本地地址
---111行 yes改成no
---309行 no改成yes
---341行 指定pid文件路径
---354行 指定日志文件路径
---504行 指定持久化文件存放位置
---1037行 可以将requirepass后面的内容换成密码,并取消注释
vim /usr/lib/systemd/system/redis-server.service
[Unit]
Description=Redis Server
After=network.target[Service]
User=redis
Group=redis
Type=forking
TimeoutSec=0
PIDFile=/usr/local/redis/pid/redis_6379.pid
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true[Install]
WantedBy=multi-user.target
redis-server:Redis 服务器启动命令
redis-benchmark:性能测试工具,用于检测 Redis 在本机的运行效率
redis-check-aof:修复有问题的 AOF 持久化文件
redis-check-rdb:修复有问题的 RDB 持久化文件
redis-cli:Redis 客户端命令行工具
redis-sentinel:Redis 哨兵集群使用
语法:redis-cli -h host -p port [-a password]
-h :指定远程主机
-p :指定 Redis 服务的端口号
-a :指定密码,未设置数据库密码可以省略-a 选项
若不添加任何选项表示,则使用 127.0.0.1:6379 连接本机上的 Redis 数据库
redis-benchmark 是官方自带的 Redis 性能测试工具,可以有效的测试 Redis 服务的性能。
基本的测试语法:redis-benchmark [选项] [选项值]。
-h :指定服务器主机名。
-p :指定服务器端口。
-s :指定服务器 socket
-c :指定并发连接数。
-n :指定请求数。
-d :以字节的形式指定 SET/GET 值的数据大小。
-k :1=keep alive 0=reconnect 。
-r :SET/GET/INCR 使用随机 key, SADD 使用随机值。
-P :通过管道传输请求。
-q :强制退出 redis。仅显示 query/sec 值。
--csv :以 CSV 格式输出。
-l :生成循环,永久执行测试。
-t :仅运行以逗号分隔的测试命令列表。
-I :Idle 模式。仅打开 N 个 idle 连接并等待。
字符串(string)、列表(list)、哈希/散列(hash)、无序集合(set)、有序集合((sorted set)/zset)
概述:String是redis最基本的类型,最大能存储512MB的数据,String类型是二进制安全的,即可以存储任何数据、比如数字、图片、序列化对象等
字符串类型的命令:
SET/GET/APPEND/STRLEN:
exists k1 #判断k1键是否存在,存在返回1,否则返回0
append k1 "hello" #因为k1键不存在,所以append命令返回k1的长度
append k1 "world" #因为k1键已存在,因此返回追加后的长度
get k1 #获取该键的值
set k2 "this is a test" #定义一个键k2,并赋值this is a test
strlen k2 #返回k2键的字符长度
INCR/DECR/INCRBY/DECRBY:
set k3 10 #定义键k3,并赋值10
incr k3 #让键k3自增1
decr k3 #让键k3自减1
del k2 #删除键k2
decr k1 #让键k1自减
del k1 #删除键k1
incr k3 #让k3键自增1
set k1 hello #定义k1键,并赋值hello
incr k1 #让键k1自增1 ,会发现报错,因为k1的值是字符串
set k1 10 #重新给k1键赋值
decrby k1 5 #指定k1键自减5
incrby k1 2 #指定k1键自增2
GETSET/SETEX/SETNX/MSET/MGET:
getset 键名 值 #在获取值的同时,赋值新的值
如:
incr k3
getset k3 8
get k3
setex 键名 过期时间 值 #设置键名的过期时间
ttl 键名 查看键名还剩多长时间过期,返回生剩余时间,返回-2表示已过期
setnx 键名 值 #定义不可覆盖值得键
如:
setnx k3 15
setnx k3 20 #返回0,因为k3键已经存在
get k3
mset 键1名 值1 键2名 值2 .... #批量定义键并赋值
mget 键1 键2 ..... #批量获取键值
如:
mset k4 "hello" k5 "world"
mget k4 k5
概述:列表的元素类型为string,按照插入顺序排序,在列表的头部或尾部添加元素
LPUSH/LPUSHX/LRANGE:
lpush 键名 值1 值2 值3 值4... #在列表键中从左到右依次插入值
lrange 键名 列表的起始下标 列表结束下标 #查看列表键中从哪个下标到哪个下标的值
lpushx 键名 值 #若键名存在,则可以插入值,且返回当中的元素数量,若键名不存在,则不能插入值
如:
lpush k1 a b c d
lrabge k1 0 -1 #0表示第一个元素,-1表示最后一个元素
lpushx k2 e
lpush k1 e
hset 键 字段1 值1 #为键设置字段,并赋值
hget 键 字段 #获取键字段的值
hdel 键 字段 #删除键中的字段
概述:无序集合,元素类型为String类型,元素具有唯一性,不允许存在重复的成员。多个集合类型之间可以进行并集、交集和差集运算。
应用范围:
1.可以使用Redis的Set数据类型跟踪一些唯一性数据,比如访问某一博客的唯一IP地址信息。对于此场景,我们仅需在每次访问该博客时将访问者的IP存入Redis中,Set数据类型会自动保证IP地址的唯一性。
2.充分利用Set类型的服务端聚合操作方便、高效的特性,可以用于维护数据对象之间的关联关系。比如所有购买某一电子设备的客户ID被存储在一个指定的Set中,而购买另外一种电子产品的客户ID被存储在另外一个Set中,如果此时我们想获取有哪些客户同时购买了这两种商品时,Set的intersections命令就可以充分发挥它的方便和效率的优势了。
sadd 键 值1 值2 值3 ..... #增加无序集合键 并赋值
smembers 键 #查看无序集合键中的值
srem 键 值 .... #移除无序集合中的某个值
zadd 键 序号 值1 序号 值2 ... #在有序集合中添加成员
zrange 键 起始下标 终止下标 [withscores] #查看从多少到多少的成员,withscore表示所有成员
zrangebyscore 键 序号1 序号2 #批量查看满足条件的成员
zrem 键 值1 值2 #移除有序集合中的成员
zremrangebyscore 键 序号1 序号2 #删除满足条件的成员
ype 键 查看键的数据类型
keys 键 * ? 查询键,支持通配符 * ?
exists 键 判断键是否存在
expire 键 过期秒数 为已存在的键设置过期时间
ttl 键 查看键的生命周期时间,-1表示永不过期,-2表示已过期
rename 旧键 新键 重命名键名,会覆盖已存在的键的值
renamenx 旧键 新键 重命名键名,如果新键已存在则不执行重命名操作
dbsize 统计当前库的键的数量
select 库ID 切换库,默认库ID为 0~15
move 键 库ID 移动键到指定的库
flushdb 清空当前库(慎用)
flushall 清空所有库(慎用)
config set requirepass 密码 设置/修改redis密码
config get requirepass 查询redis密码
auth 密码 在redis中验证密码
持久化的功能:Redis是内存数据库,数据都是存储在内存中,为了避免服务器断电等原因导致Redis进程异常退出后数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘;当下次Redis重启时,利用持久化文件实现数据恢复。除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。
Redis 提供两种方式进行持久化:
●RDB 持久化:原理是将 Reids在内存中的数据库记录定时保存到磁盘上。
●AOF 持久化(append only file):原理是将 Reids 的操作日志以追加的方式写入文件,类似于MySQL的binlog。
由于AOF持久化的实时性更好,即当进程意外退出时丢失的数据更少,因此AOF是目前主流的持久化方式,不过RDB持久化仍然有其用武之地。
RDB持久化是指在指定的时间间隔内将内存中当前进程中的数据生成快照保存到硬盘(因此也称作快照持久化),用二进制压缩存储,保存的文件后缀是rdb;当Redis重新启动时,可以读取快照文件恢复数据。
RDB持久化的触发分为手动触发和自动触发两种。
1)手动触发
save命令和bgsave命令都可以生成RDB文件。
save命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在Redis服务器阻塞期间,服务器不能处理任何命令请求。
bgsave命令会创建一个子进程,由子进程来负责创建RDB文件,父进程(即Redis主进程)则继续处理请求。
2)自动触发
在自动触发RDB持久化时,Redis也会选择bgsave而不是save来进行持久化。
触发机制有save n m ,指定当m秒内发生n次变化时,会触发bgsave进行快照。
在redis.conf文件中配置RDB保存策略
vim /usr/local/redis/conf/redis.conf
--433行--RDB默认保存策略
# save 3600 1 300 100 60 10000表示以下三个save条件满足任意一个时,都会引起bgsave的调用
save 3600 1 :当时间到3600秒时,如果redis数据发生了至少1次变化,则执行bgsave
save 300 10 :当时间到300秒时,如果redis数据发生了至少10次变化,则执行bgsave
save 60 10000 :当时间到60秒时,如果redis数据发生了至少10000次变化,则执行bgsave
-454行--是否开启RDB文件压缩
rdbcompression yes
--481行--指定RDB文件名
dbfilename dump.rdb
--504行--指定RDB文件和AOF文件所在目录
dir /usr/local/redis/data
其他自动触发机制
除了save m n 以外,还有一些其他情况会触发bgsave:
●在主从复制场景下,如果从节点执行全量复制操作,则主节点会执行bgsave命令,并将rdb文件发送给从节点。
●执行shutdown命令时,自动执行rdb持久化。
(1)Redis父进程首先判断:当前是否在执行save,或bgsave/bgrewriteaof的子进程,如果在执行则bgsave命令直接返回。 bgsave/bgrewriteaof的子进程不能同时执行,主要是基于性能方面的考虑:两个并发的子进程同时执行大量的磁盘写操作,可能引起严重的性能问题。
(2)父进程执行fork操作创建子进程,这个过程中父进程是阻塞的,Redis不能执行来自客户端的任何命令
(3)父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令
(4)子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后对原有文件进行原子替换
(5)子进程发送信号给父进程表示完成,父进程更新统计信息
RDB持久化是将进程数据写入文件,而AOF持久化,则是将Redis执行的每次写、删除命令记录到单独的日志文件中,查询操作不会记录; 当Redis重启时再次执行AOF文件中的命令来恢复数据。
与RDB相比,AOF的实时性更好,因此已成为主流的持久化方案。
Redis服务器默认开启RDB,关闭AOF;要开启AOF,需要在配置文件中配置:
vim /usr/local/redis/conf/redis.conf
--1380行--修改,开启AOF
appendonly yes
--1407行--指定AOF文件名称
appendfilename "appendonly.aof"
--1505行--是否忽略最后一条可能存在问题的指令
aof-load-truncated yes
systemctl restart redis-server.service
由于需要记录Redis的每条写命令,因此AOF不需要触发,下面介绍AOF的执行流程。
AOF的执行流程包括:
●命令追加(append):将Redis的写命令追加到缓冲区aof_buf;
●文件写入(write)和文件同步(sync):根据不同的同步策略将aof_buf中的内容同步到硬盘;
●文件重写(rewrite):定期重写AOF文件,达到压缩的目的。
1)定时把redis内存中的数据进行快照并压缩保存到硬盘
2)RDB持久化保存的文件占用空间小,网络传输快
3)恢复速度也比AOF快,性能影响比AOF更小
4)实时性不如AOF,兼容性较差,持久化期间在fork子进程时会阻塞reids父进程
1)以追加的方式将redis写操作的命令记录到文件中
2)实时性比RDB好,支持秒级持久化,兼容性较好
3)持久化保存的文件占用磁盘空间更大,恢复速度更慢,性能影响更大
4)AOF文件重写期间在fork子进程时会阻塞reids父进程
1)设置 config set activedefrag yes 开启内存碎片自动清理,或者定时执行 memory purge 清理内存碎片
2)设置 maxmemory 指定redis可占用的最大内存大小
设置 maxmemory-policy 指定内存数据淘汰策略,实现保存内存使用率不超过最大内存
设置 maxmemory-samples 指定内存数据淘汰策略的样本数量,值越大越精确(默认为5)
设置 maxclients 指定最大客户端连接数
设置 tcp-backlog 指定最大连接排队数
设置 timeout 指定连接超时时间
3)尽可能使用 hash 数据类型存储数据。因为 hash 类型的一个 key 可包含多个字段,该类型的数据占用空间较小
4)建议设置 key 的过期时间,精简 键名和键值,控制键占用空间的大小
5)设置 AOF持久化 和 主从复制 来备份数据,采用 哨兵 或 集群 模式实现集群的高可用
6)建议通过命令 config set requirepass 或 修改配置文件 requirepass 参数来设置redis密码