Redis简介
Redis(RemoteDictionaryServer,远程字典型)是一个开源的、使用 C语言编写的NoSQL数据库。Redis 基于内存运行并支持持久化,采用 key-value(键值对)的存储形式,是目前分布式架构中不可或缺的一环
Redis优点:
- 具有极高的数据读写速度,数据读取的速度最高可达到 110000 次/s,数据写入速度最高可达到 81000 次/s
- 支持丰富的数据类型,不仅仅支持简单的 key-value 类型的数据,还支持 Strings,ListsHashes,Sets 及 Ordered Sets 等数据类型操作
- 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用
- 原子性,Redis 所有操作都是原子性的
- 支持数据备份,即 master-salve 模式的数据备份
1.关系型数据库
- 关系型数据库是一个结构化的数据库,创建在关系模型基础上,一般面向于记录
- 它借助于集合代数等数学概念和方法来处理数据库中的数据
- 关系模型就是指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织
- SQL语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型数据库中数据的检索和操作
- 主流的关系型数据库包括 Oracle、MySQL、SQLServer、Microsoft Access、DB2 等
2.非关系型数据库
- NoSQL(NoSQL= Not Only SQL),意思是“不仅仅是 SQL”,是非关系型数据库的总称
- 这些非关系型数据库,他们的存储方式、存储结构以及使用的场景都是完全不同的
- 它是一个非关系型数据库的集合,而不是像关系型数据库一样,是一个统称
- 主流的 NoSQL 数据库有 Redis、MongBD、Hbase、CouhDB 等
3.非关系型数据库产生背景:三高问题
- High performance--对数据库高并发读写需求:关系型数据库对于上万次的查询请求还是可以勉强支撑的,但出现上万次的写数据请求,硬盘 10 就已经无法承受了。对于普通的 BBS 网站,往往也会存在高并发的写数据请求
- Huge Storage--对海量数据高效存储与访问需求:类似于 Facebook、Friendfeed 这样的 SNS 网站,每天会产生大量的用户动态信息。如 Friendfeed,一个月就会产生不少于 2.5亿条用户动态信息,对于关系型数据库来说,在一个包含 2.5 亿条记录的表中执行 SQL查询,查询效率是非常低的
- High Scalability && High Availability--对数据库高可扩展性与高可用性需求:关系型数据库和非关系型数据库都有各自的特点与应用场景,两者的紧密结合将会给Web2.0的数据库发展带来新的思路。让关系数据库关注在关系上,非关系型数据库关注在存储上
一、redis安装部署
1.安装
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# yum -y install gcc* zlib-devel
[root@localhost ~]# tar xvzf redis-4.0.9.tar.gz
[root@localhost ~]# cd redis-4.0.9/
[root@localhost redis-4.0.9]# make
//make命令可能会错误提示:
//解决方法1:用make MALLOC=libc指定内存分配器为 libc进行编译
//解决方法2:make clean && make distclean
[root@localhost redis-4.0.9]# make PREFIX=/usr/local/redis install
[root@localhost ~]# ln -s /usr/local/redis/bin/* /usr/local/bin/
[root@localhost redis-4.0.9]# cd /root/redis-4.0.9/utils/
[root@localhost utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port : 6379
Config file : /etc/redis/6379.conf
Log file : /var/log/redis_6379.log
Data dir : /var/lib/redis/6379
Executable : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
[root@localhost utils]# netstat -anpt | grep redis //最后查看进程
- Config file : /etc/redis/6379.conf //配置文件路径
- Log file : /var/log/redis_6379.log //日志文件路径
- Data dir : /var/lib/redis/6379 //数据文件路径
- Executable : /usr/local/redis/bin/redis-server //可执行文件路径
- Cli Executable : /usr/local/redis/bin/redis-cli //客户端命令行工具
2.服务控制
[root@localhost ~]#/etc/init.d/redis_6379 stop
[root@localhost ~]#/etc/init.d/redis_6379 start
[root@localhost ~]#/etc/init.d/redis_6379 restart
[root@localhost ~]#/etc/init.d/redis_6379 status
3.配置参数的修改
[root@localhost ~]#vim /etc/redis/6379.conf
bind 127.0.0.1 192.168.10.101 //监听的主机地址
port 6379 //端口
daemonize yes //启用守护进程
pidfile /var/run/redis_6379.pid //指定 PID 文件
loglevel notice //日志级别
logfile /var/log/redis_6379.log //指定日志文件
[root@localhost~]#/etc/init.d/redis_6379 restart
[root@localhost utils]# netstat -anpt | grep redis
Redis配置参数 | |
timeout 300 | 当客户端闲置多长时间后关闭连接,如果指定为0表示关闭该功能 |
dbfilename dump.rdb | 指定本地数据库文件名,默认值为 dump.rdb |
dir /var/lib/redis/6379 | 指定本地数据库存放目录 |
maxclients 10000 | 设置同一时间最大客户端连接数,默认为10000:Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients0,表示不限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回 max number ofclients reached 错误信息 |
rdbcompression yes | 指定存储至本地数据库时是否压缩数据,默认为 yesRedis 采用 LZF 压缩,如果为了节省 CPU 资源,可以关闭该选项,但会导致数据库文件变的巨大 |
slaveof | 当本机为从服务器时,设置主服务的IP地址及端口:在 Redis 启动时,从服务器会自动从主服务进行数据同步 |
masterauth | 当主服务设置了密码保护时,从服务连接主服务的密码 |
requirepass foobared | 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH 命令提供密码,默认关闭 |
maxmemory | 指定 Redis 最大内存限制。Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis 新 VM 机制,会把 Key 存放内存,Value 会存放在 Swap 分区 |
appendonly no | 指定是否在每次更新操作后进行日志记录,Redis 在默认情况下是异步地把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为Redis 本身同步数据文件是按上面 save 条件来同出的,所以有的数据会在一段时间内只存在于内存中。默认为 no |
appendfilename appendonly.aof | 指定更新日志文件名,默认为 appendonly.aof |
appendfsync everysec | 指定更新日志条件,共有3个可选值: no:表示等操作系统进行数据缓存同步到磁盘(快) always:表示每次更新操作后手动调用 fsync()将数据写到磁盘(慢,安全) everysec:表示每秒同步一次(折衷,默认值) |
activerehashing yes | 指定是否激活重置哈希,默认为开启 |
include /path/to/local.conf | 指定包含其它的配置文件,可以在同一主机上多个Redis 实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件 |
4.redis-cli 命令行工具
//安装 Redis 服务时,所包含的软件工具会同时被安装到系统中,在系统中可以直接使用
redis-server:用于启动 Redis 的工具;
redis-benchmark:用于检测 Redis 在本机的运行效率:
redis-check-aof:修复 AOF 持久化文件;
redis-check-rdb:修复 RDB 持久化文件:
redis-cli: Redis 命令行工具。
(1)连接本机redis
[root@localhost ~]# redis-cli
127.0.0.1:6379>
(2)测试redis服务是否启动
127.0.0.1:6379> ping
PONG
(3)远程连接
[root@localhost ~]#redis-cli -h 192.168.10.101 -p 6379
//获取帮助
help @<group>:获取<group>中的命令列表; //127.0.0.1:6379>help @list
help <command>:获取某个命令的帮助; //127.0.0.1:6379>help set
help <tab>:获取可能帮助的主题列表。 //输入help后,按下tab键
5.redis-benchmark 测试工具
//redis-benchmark 是官方自带的 Redis 性能测试工具,可以有效的测试 Redis 服务的性能
-h:指定服务器主机名;
-p:指定服务器端口;
-s:指定服务器 socket;
-c:指定并发连接数;
-n:指定请求数;
-d:以字节的形式指定 SET/GET 值的数据大小;
-k:1=keep alive 0=reconnect;
-r:SET/GET/INCR 使用随机 key, SADD 使用随机值;
-P:通过管道传输<numreq>请求;
-q:强制退出 redis。仅显示 query/sec 值;
--csv:以 CSV 格式输出;
-l:生成循环,永久执行测试;
-t:仅运行以逗号分隔的测试命令列表;
-I:Idle 模式。仅打开 N 个 idle 连接并等待。
Redis 数据库常用命令
set:存放数据,基本的命令格式为 set key value。
get:获取数据,基本的命令格式为 get key。
127.0.0.1:6379>set teacher zhanglong
127.0.0.1:6379>get teacher
(1)添加键值对
//使用 keys 命令可以取符合规则的键值列表,通常情况可以结合*、?等选项来使用
127.0.0.1:6379>set k1 1
OK
127.0.0.1:6379>set k2 2
OK
127.0.0.1:6379>set k3 3
OK
127.0.0.1:6379>set v1 4
OK
127.0.0.1:6379>set v5 5
OK
(2)查看当前数据库中所有键
127.0.0.1:6379>KEYS *
127.0.0.1:6379>set v22 5
OK
(3)查看当前数据库中以 v 开头的数据
127.0.0.1:6379>KEYS v*
1) "v1"
2) "v5"
3) "v22"
(4)查看当前数据库中以 v 开头后面包含任意一位的数据
127.0.0.1:6379>KEYS v?
1) "v1"
2) "v5"
(5)查看当前数据库中以 v 开头 v 开头后面包含任意两位的数据
127.0.0.1:6379>KEYS v??
1) "v22"
(2)exists
exists 命令可以判断键值是否存在
127.0.0.1:6379>exists teacher
(integer) 1
结果为1,表示 teacher 键是存在
127.0.0.1:6379>exists tea
(integer) 0
结果为0,表示 tea 键不存在
(3)del
del 命令可以删除当前数据库的指定 key
127.0.0.1:6379>keys *
1) "teacher"
2) "v1"
3) "v22"
4) "k3"
5) "k1"
6) "k2"
7) "v5"
127.0.0.1:6379> del v5
(integer) 1
127.0.0.1:6379>get v5
(nil)
(4)type
使用 type 命令可以获取 key 对应的 value 值类型
127.0.0.1:6379>type k1
string
redis支持的数据类型
String:最简单的类型,就是普通的set和get,作key value缓存。
Hash:类似map的一种结构,一般就是可以将结构化的数据,比如一个对象给缓存在redis里
List:List是有序列表,可以通过list存储一些列表型的数据结构,类似粉丝列表、文章的评论列表之类的东西
Set:Set是无序集合,自动去重。
Sorted Set:Sorted Set是排序的set,去重但可以排序,写进去的时候给一个分数,自动根据分数排序
(5)rename
//rename 命令是对已有 key 进行重命名
//在实际使用过程中,建议先用 exists 命令查看目标 key 是否存在,然后再决定是否执行 rename 命令,以避免覆盖重要数据
127.0.0.1:6379>keys v*
1) "v1"
2) "v22"
127.0.0.1:6379>rename v22 v2
OK
127.0.0.1:6379>keys v*
1) "v1"
2) "v2"
127.0.0.1:6379>get v1
"4"
127.0.0.1:6379>get v2
"5"
127.0.0.1:6379>rename v1 v2
OK
127.0.0.1:6379>get v1
(nil)
127.0.0.1:6379>get v2
"4"
(6)renamenx
//renamenx 命令的作用是对已有 key 进行重命名,并检测新名是否存在//使用renamenx 命令进行重命名时,如果目标 key 存在则不进行重命名
127.0.0.1:6379>keys *
1) "teacher"
2) "k3"
3) "k1"
4) "k2"
5) "v2"
127.0.0.1:6379>get teacher
"zhanglong"
127.0.0.1:6379>get v2
"4"
127.0.0.1:6379>renamenx v2 teacher
(integer) 0
127.0.0.1:6379>keys *
1) "teacher"
2) "k3"
3) "k1"
4) "k2"
5) "v2"
127.0.0.1:6379>get teacher
"zhanglong"
127.0.0.1:6379>get v2
"4
(7)dbsize
dbsize 命令的作用是查看当前数据库中 key 的数目。
127.0.0.1:6379> dbsize
(integer) 5
多数据库常用命令
(1)多数据库间切换
//Redis 在没有任何改动的情况下默认包含 16 个数据库,数据库名称是用数字 0-15 来依次命名的
(1)切换至序号为 10 的数据库
127.0.0.1:6379>select 10
OK
(2)切换至序号为 15 的数据库
127.0.0.1:6379[10]>select 15
OK
(3)切换至序号为 0 的数据库
127.0.0.1:6379[15]>select 0
(2)多数据库间移动数据
//Redis 的多数据库在一定程度上是相对独立的,例如在数据库 0 上面存放 k1 的数据,在其它 1-15 的数据库上是无法查看到的。
127.0.0.1:6379>set k1 100
OK
127.0.0.1:6379>get k1
"100"
127.0.0.1:6379>select 1
OK
127.0.0.1:6379[1]>get k1
(nil)
127.0.0.1:6379[1]>select 0 //切换至目标数据库 0
OK
127.0.0.1:6379>get k1 //查看目标数据是否存在
"100"
127.0.0.1:6379>move k1 1 //将数据库 0 中 k1 移动到数据库 1 中
(integer) 1
127.0.0.1:6379>select 1 //切换至目标数据库 1
OK
127.0.0.1:6379[1]>get k1 //查看被移动数据
"100"
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> get k1 //在数据库 0 中无法查看到 k1 的值
(nil)
(3)清除数据库内数据
Redis 持久化清空当前数据库数据,使用 FLUSHDB 命令实现;
清空所有数据库的数据,使用 FLUSHALL 命令实现
二、ROB持久化:ROB和AOF
- BOB:RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发,触发机制:手动触发分别对应为save和bgsave命令
- save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较多的实例会造成时间阻塞。线上环境不建议使用
- bgsave命令:Redis进程执行fork(用于创建进程的函数)操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段
- RDB的优点:RDB是一个紧凑压缩的二进制文件,代表Redis在某一个时间点上的数据快照。非常适用于备份,全量复制等场景。适合大规模的数据恢复
- 业务对数据一致性要求不高
- Redis加载RDB恢复数据远远快于AOF方式
- RDB的缺点:RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都有执行fork操作创建子进程,属于重量级操作,频繁执行成本过高
- RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题
- AOF:AOF(append only file)持久化以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流
- AOF优点:AOF 机制可以带来更高的数据安全性,即数据持久性;Redis 中提供了3种同步策略,即每秒同步、每次修改同步和不同步
- 于该机制对日志文件的写入操作采用的是 append 模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容,然而如果本次操作只是写入了一半数据就出现了系统崩溃问题,那么在 Redis 下一次启动之前,可以通过 redis-check-aof工具来解决数据一致性的问题
- 如果日志过大,Redis 可以自动启用 rewrite 机制。即 Redis 以 append 模式不断地将修改数据写入到老的磁盘文件中,同时 Redis 还会创建一个新的文件用于记录此期间有哪些修改命令被执行
- AOF缺点:对于相同数量的数据集而言,AOF 文件通常要大于 RDB 文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
- 根据同步策略的不同,AOF 在运行效率上往往会慢于RDB。每秒同步策略的效率是比较高的,同步禁用策略的效率和 RDB 一样高效
牺牲一些性能,换取更高的缓存一致性(AOF), 写操作频繁的时候,不启用备份来换取更高的性能,待手动运行 save 的时候,再做备份(RDB)
如果redies重启之后,需要加载一个持久化文件,有限会选择AOF文件。如果先开启了RDB,再开启AOF,RDB先执行了持久化,那么RDB文件中的内容会被AOF覆盖掉
1、Redis 持久化配置
[root@localhost ~]# vim /etc/redis/6379.conf
//打开 6379.conf 文件之后,搜索 save,可以看到如下所示配置信息
save 900 1:在 900 秒(15 分钟)之后,如果至少有 1 个 key 发生变化,则 dump内存快照。
save 300 10:在 300 秒(5 分钟)之后,如果至少有 10 个 key 发生变化,则 dump内存快照。
save 60 10000:在 60 秒(1 分钟)之后,如果至少有 10000 个 key 发生变化,则dump 内存快照。
dbfilename dump.rdb :RDB文件名称 ##254行
dir /var/lib/redis/6379 :RDB文件路径 ##264行
rdbcompression yes :是否进行压缩 ##242行
2、AOF 持久化配置
在 Redis 的配置文件中存在三种同步方式,它们分别是:
appendonly yes :开启AOF持久化(默认为no) ##673行
appendfilename "appendonly.aof " :AOF文件名称 ##677行
# appendfsync always
appendfsync everysec
# appendfsync no
always:同步持久化,每次发生数据变化会立刻写入磁盘
everysec:默认推荐,每秒异步记录一次(默认值)
no:不同步,交给操作系统决定如何同步
aof-load-truncated yes ##769行
忽略最后一条可能存在问题的指令
[root@localhost ~]#/etc/init.d/redis_6379 restart
3、AOF重写
//为了解决 AOF 文件体积不断增大的问题,用户可以向 Redis 发送 BGREWRITEAOF命令。
//BGREWRITEAOF 命令会通过移除 AOF 文件中的冗余命令来重写(rewrite)AOF文件,使 AOF 文件的体积尽可能地变小
127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started
//在日志进行BGREWRITEAOF时,如果no-appendfsync-on-rewrite设置为yes表示新写操作不进行同步fsync,
//只是暂存在缓冲区里,避免造成磁盘IO操作冲突,等重写完成后再写入。Redis中默认为no
no-appendfsync-on-rewrite no
//当前AOF文件大小是上次日志重写时AOF文件大小两倍时,发生BGREWRITEAOF操作
auto-aof-rewrite-percentage 100 //100指的是aof文件增长比例,指当前aof文件比上次重写的增长比例大小,100为两倍
//当前AOF文件执行BGREWRITEAOF命令的最小值,避免刚开始启动Reids时由于文件尺寸较小导致频繁的BGREWRITEAOF
auto-aof-rewrite-min-size 64mb
三、性能管理
(1)查看内存信息
192.168.9.236:7001> info memory
used_memory:1210776 #已经内存使用的大小,以字节为单位
used_memory_human:1.15M # 带单位展示,以M为单位
used_memory_rss:7802880 # 从操作系统角度看redis内存占用多少
used_memory_rss_human:7.44M # 带单位展示
maxmemory:1073741824 # 最大内存大小
maxmemory_human:1.00G # 带单位展示
(2)回收策略
maxmemory-policy:回收策略
volatile-lru:它允许 Redis 从整个数据集中挑选最近最少使用的 key 进行删除
volatile-ttl:按照key的过期时间进行淘汰
volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰;
allkeys-lru:使用 LRU 算法从所有数据集合中淘汰数据;
allkeys-random:从数据集合中任意选择数据淘汰;
noeviction:禁止淘汰数据(默认值)
//设置key的过期时间
expire v1 10
//v1的过期时间为10秒
//当 Redis 由于内存压力需要回收一个 key 时,Redis 首先考虑的不是回收最旧的数据,而是在最近最少使用的 key 或即将过期的 key 中随机选择一个 key,从数据集中删除
四、Redis设置密码
(1)通过配置文件redis.conf设置密码
找到requirepass关键字,后面就是跟的密码,默认情况下是注释掉的,即默认不需要密码
打开注释,设置为自己的密码,重启即可
(2)通过命名设置密码
使用redis-cli连接上redis,执行如下命令
config set requirepass 123456
执行完毕,无需重启,退出客户端,重新登录就需要输入密码了
连接方法
1、连接时输入密码
[root@localhost bin]# ./redis-cli -a 123456
2、先连接再输入密码
[root@localhost bin]# ./redis-cli127.0.0.1:6379> auth 123456
关闭方法
[root@localhost bin]# ./redis-cli -a 123456 shutdown
- 修改配置文件设置的密码永久生效;使用命令设置的密码临时生效,重启后失效
- 修改配置文件设置的密码,需要重启生效;使用命令设置的密码,退出后再登录生效,重启后失效
- 命令的优先级高于配置文件的优先级