Redis 配置教程 常用命令 持久化 缓存问题

Redis 实用教程


一、Redis简介

1.redis是什么

Redis是一款开源的,ANSI C语言编写的,高级键值(key-value)缓存和支持永久存储NoSQL数据库产品。
Redis采用内存(In-Memory)数据集(DataSet) 。
支持多种数据类型。
运行于大多数POSIX系统,如Linux、*BSD、OS X等。

redis就是非关系型数据库的一种,存储方式是:key:value

2.redis的作用

1.会话保持(键过期)
2.缓存(放在数据库前面,memcache,mongodb)
3.消息队列(kafka)

3.为什么要用Redis

1.redis功能全面
2.redis企业使用率高

4.redis优点

1.高速读写
    将所有数据存储在内存,单线程服务,使用C语言
2.部署简单,使用稳定
3.数据类型丰富
    String: 字符串类型
    Hash: 哈希类型
    List: 列表类型
    Set: 集合类型
    Sorted set: 顺序集合类型
4.支持持久化
    将内存的数据写入磁盘
5.多种内存分配及回收策略
6.支持事物、锁
7.消息队列、消息订阅
8.支持高可用
    哨兵模式
9.支持分布式分片集群
10.支持的客户端语言很多
    java,php,python,nodejs,C语言

5.redis帮助

官方网站:https://redis.io/
下载网站:http://download.redis.io/releases/
帮助网站:http://redisdoc.com/

6.缓存服务对比

#Memcached:
1.优点:高性能读写、单一数据类型、支持客户端式分布式集群、一致性hash多核结构、多线程读写性能高。
2.缺点:无持久化、节点故障可能出现缓存穿透、分布式需要客户端实现、跨机房数据同步困难、架构扩容复杂度高

#Redis:
1.优点:高性能读写、多数据类型支持、数据持久化、高可用架构、支持自定义虚拟内存、支持分布式分片集群、单线程读写性能极高
2.缺点:多线程读写较Memcached慢

#Tair:
1.优点:高性能读写、支持三种存储引擎(ddb、rdb、ldb)、支持高可用、支持分布式分片集群、支撑了几乎所有淘宝业务的缓存。
2.缺点:单机情况下,读写性能较其他两种产品较慢

#对比结论:
1.Memcached:多核的缓存服务,更加适合于多用户并发访问次数(访问次数较少的应用场景)。
2.Redis:单核缓存服务,在单节点情况下,更加适合少量用户,多次访问的应用场景。

二、Redis使用场景

1.缓存
    放在数据库前面
2.会话保持
    登录cookie、session
    折扣券,代金券
3.排行榜
4.计数器
    论坛帖子点赞点踩
5.社交软件
    QQ共同好友,微博共同爱好
6.消息队列
    结合ELK做日志收集

三、redis搭建

1.下载软件包

[root@db01 ~]# rz redis-3.2.12.tar.gz
或者
[root@db01 ~]# wget http://download.redis.io/releases/redis-3.2.12.tar.gz

2.安装依赖

[root@db01 ~]# yum install -y gcc gcc-c++

3.解压移动

[root@db01 ~]# tar xf redis-3.2.12.tar.gz 
[root@db01 ~]# mv redis-3.2.12 /usr/local/
[root@db01 ~]# ln -s /usr/local/redis-3.2.12 /usr/local/redis

4.安装

[root@db01 ~]# cd /usr/local/redis
[root@db01 redis]# make

或者使用建议安装
[root@db01 redis]# make && make install

5.启动redis

[root@db01 redis]# ./src/redis-server &

[root@db01 redis]# netstat -lntp  
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      11759/./src/redis-s

6.连接redis

#配置环境变量
[root@db01 redis]# vim /etc/profile.d/redis.sh
export PATH=/usr/local/redis/src:$PATH

#连接
[root@db01 redis]# redis-cli 
127.0.0.1:6379> 

#连接后可以显示中文的key和value
[root@db01 redis]# redis-cli --raw

#在库外执行(类似mysql -e)
redis-cli set a 1
redis-cli get a

7.关闭redis

[root@db01 redis]# redis-cli shutdown
11759:M 03 Aug 10:20:20.535 # User requested shutdown...
11759:M 03 Aug 10:20:20.535 * Saving the final RDB snapshot before exiting.
11759:M 03 Aug 10:20:20.546 * DB saved on disk
11759:M 03 Aug 10:20:20.546 # Redis is now ready to exit, bye bye...
[1]+  Done                    ./src/redis-server


[root@db01 redis]# redis-cli 
127.0.0.1:6379> shutdown
11851:M 03 Aug 10:20:59.580 # User requested shutdown...
11851:M 03 Aug 10:20:59.580 * Saving the final RDB snapshot before exiting.
11851:M 03 Aug 10:20:59.584 * DB saved on disk
11851:M 03 Aug 10:20:59.584 # Redis is now ready to exit, bye bye...
not connected> quit
[1]+  Done                    ./src/redis-server

四、redis配置文件

1.配置

#默认的配置文件
[root@db01 redis]# pwd
/usr/local/redis
[root@db01 redis]# ll
-rw-rw-r--  1 root root 46695 Jun 13  2018 redis.conf

#创建reids配置文件目录
[root@db01 redis]# mkdir /service/redis/6379 -p

#编写配置文件
[root@db01 redis]# vim /service/redis/6379/redis.conf
bind 172.16.1.51 127.0.0.1                          #监听地址
requirepass 123456

port 6379                                          #端口
daemonize no                                       #后台启动
pidfile /service/redis/6379/redis_6379.pid            #指定pid文件
loglevel notice                                     #指定日志级别
logfile /service/redis/6379/redis_6379.log            #指定日志文件

dir /data/6379
#持久化文件位置
dbfilename dump.rdb
#持久化文件名(就一个)
--------------------

redis-cli -a 123456 -h 172.16.1.51 -p6379
# 通过密码,ip,端口登录.
# 或者登录后auth输入密码 

2.指定配置文件启动

[root@db01 redis]# redis-server /service/redis/6379/redis.conf &

五、redis操作

1.基本操作

KEYS * keys a keys a* 查看已存在所有键的名字
TYPE 返回键所存储值的类型
EXPIRE\ PEXPIRE 以秒\毫秒设定生存时间
TTL\ PTTL 以秒\毫秒为单位返回生存时间
PERSIST 取消生存时间设置
DEL 删除一个key
EXISTS 检查是否存在
RENAME 变更KEY名

1.连接redis
    [root@db01 redis]# redis-cli 
    127.0.0.1:6379>
2.查看所有数据
    127.0.0.1:6379> keys *
    (empty list or set)
    #查看时注意不要轻易使用,如想查看数据,先查看数据量DBSIZE
    127.0.0.1:6379> DBSIZE
    (integer) 2018041
3.添加数据
    127.0.0.1:6379> set k1 v1
    OK
4.查看数据
    127.0.0.1:6379> keys *
    1) "k1"
    127.0.0.1:6379> get k1
    "v1"
5.删除数据
    127.0.0.1:6379> keys *
    1) "k1"
    127.0.0.1:6379> DEL k1
    (integer) 1
    127.0.0.1:6379> keys *
    (empty list or set)
6.修改数据
    127.0.0.1:6379> set k1 v1
    OK
    127.0.0.1:6379> set k1 v11111
    OK
    127.0.0.1:6379> get k1
    "v11111"
7.追加数据
    127.0.0.1:6379> APPEND k1 000000
    (integer) 12
    127.0.0.1:6379> get k1
    "v11111000000"
8.切换库(默认在库0,一共只到库15)
    127.0.0.1:6379> SELECT 1
    OK
    127.0.0.1:6379[1]> SELECT 2
    OK
    127.0.0.1:6379[2]> SELECT 3
    OK
    127.0.0.1:6379> SELECT 16
    (error) ERR invalid DB index

2.密码的设置

1.配置文件配置密码
    [root@db01 redis]# vim redis.conf 
    requirepass 123

2.使用密码连接
    [root@db01 redis]# redis-cli -a 123

3.登陆后输入密码
    [root@db01 redis]# redis-cli
    127.0.0.1:6379> AUTH 123
    OK
    127.0.0.1:6379> DBSIZE
    (integer) 2018041

4.redis连接后获取密码
    127.0.0.1:6379> CONFIG GET requirepass
    1) "requirepass"
    2) "123"

5.redis连接后修改密码
    127.0.0.1:6379> CONFIG set requirepass 234
    OK
    [root@db01 redis]# redis-cli
    127.0.0.1:6379> DBSIZE
    (error) NOAUTH Authentication required.
    127.0.0.1:6379> auth 123
    (error) ERR invalid password
    127.0.0.1:6379> auth 234
    OK

# 6.查看参数和修改配置
    127.0.0.1:6379> config get requirepass
    127.0.0.1:6379> config get maxmemory
    127.0.0.1:6379> config get *
    127.0.0.1:6379> config get requi*
常用设置内存(一般单节点推荐系统的70%左右)
    127.0.0.1:6379> config set maxmemory 1024M

# 设置完之后需要保存
    127.0.0.1:6379> config rewrite
大部分配置可以在线保存.个别不行.

3.通用操做

1.判断key是否存在
    127.0.0.1:6379> EXISTS k1
    (integer) 1                     #存在则返回1
    127.0.0.1:6379> EXISTS k2
    (integer) 0                     #不存在则返回0
2.修改key的名字
    127.0.0.1:6379> KEYS *
    1) "k1"
    127.0.0.1:6379> RENAME k1 k100
    OK
    127.0.0.1:6379> KEYS *
    1) "k100"
3.查看数据类型
    127.0.0.1:6379> TYPE k100
    string
4.设置生存时间
    #以秒为单位
    127.0.0.1:6379> EXPIRE qiudao 10
    (integer) 1
    #以毫秒为单位
    127.0.0.1:6379> PEXPIRE k100 10000
    (integer) 1
5.查看生存时间
    127.0.0.1:6379> TTL k100
    (integer) 1                 #正整数生存时间倒计时
    127.0.0.1:6379> TTL k100
    (integer) -1                #-1代表没有设置生存时间
    127.0.0.1:6379> TTL k100
    (integer) -2                #代表设置过生存时间已删除,已过期
6.取消生存时间
    127.0.0.1:6379> TTL qiudao
    (integer) 93
    127.0.0.1:6379> PERSIST qiudao
    (integer) 1
    127.0.0.1:6379> TTL qiudao
    (integer) -1

EXPIREAT <KEY> <timestamp> :将键的过期时间设为 timestamp 所指定的秒数时间戳
PEXPIREAT <KEY> <timestamp>: 将键的过期时间设为 timestamp 所指定的毫秒数时间戳.

六、持久化

1.什么时持久化

将内存中的数据写入到磁盘,永久保存

2.持久化的模式

#两种模式:
1.RDB模式 基于快照的持久化
2.AOF模式 类似于binlog

#save和bgsave的区别:
save: 前台,会阻塞redis正常写入,开启立即执行,直到持久化完成.
bgsave: 后台,开启子线程,异步持久化,不会阻塞.

3.RDB模式

可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot),主从复制也是基于RDB持久化功能来实现的.

1)RDB工作模式

1.默认情况下,Redis保存数据集快照到磁盘,名为dump.rdb的二进制文件。
你可以设置让Redis在N秒内至少有M次数据集改动时保存数据集,或者你也可以手动调用SAVE或者BGSAVE命令。

2.在上文中我们已经在配置文件中做过对应的配置:
例如,这个配置会让Redis在每个60秒内至少有1000次键改动时自动转储数据集到磁盘:
save 60 1000

3.当 Redis 需要保存 dump.rdb 文件时,服务器执行以下操作:
Redis 调用 fork() ,同时拥有父进程和子进程。
子进程将数据集写入到一个临时的 RDB 文件中。
当子进程完成对新 RDB 文件的写入时, Redis 用新RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

4.这种方式使得 Redis 可以从写时复制机制中获益。

2)配置RDB持久化

#编辑配置文件
[root@db01 ~]# vim /service/redis/6379/redis.conf 
bind 172.16.1.51 127.0.0.1
port 6379
daemonize yes
pidfile /service/redis/6379/redis_6379.pid
loglevel notice
logfile /service/redis/6379/redis_6379.log
#设置redis密码
requirepass 123
#持久化数据文件存储位置
dir /etc/redis/6379
#rdb持久化数据文件名
dbfilename dump.rdb
#900秒(15分钟)内有1个更改
save 900 1
#300秒(5分钟)内有10个更改
save 300 10
#60秒(1分钟)内有10000个更改
save 60 10000

3)使用RDB文件

1.先停止redis
2.将rdb文件放到指定目录下
3.启动redis

'自动写操作,save,bgsave,都会保存当前内容覆盖到dump.rdb文件,注意资料的保存,建议移动或复制到新的文件夹下。'

4)RDB持久化优点

1.RDB是一种表示某个即时点的Redis数据的紧凑文件。RDB文件适合用于备份。
例如,你可能想要每小时归档最近24小时的RDB文件,每天保存近30天的RDB快照。这允许你很容易的恢复不同版本的数据集以容灾。

2.RDB非常适合于灾难恢复,作为一个紧凑的单一文件,可以被传输到远程的数据中心。

3.RDB最大化了Redis的性能,因为Redis父进程持久化时唯一需要做的是启动(fork)一个子进程,由子进程完成所有剩余工作。
父进程实例不需要执行像磁盘IO这样的操作。

4.RDB在重启保存了大数据集的实例时比AOF要快。

4)RDB持久化缺点

1.当你需要在Redis停止工作(例如停电)时最小化数据丢失,RDB可能不太好。你可以配置不同的保存点(save point)来保存RDB文件(例如,至少5分钟和对数据集100次写之后,但是你可以有多个保存点)。然而,你通常每隔5分钟或更久创建一个RDB快照,所以一旦Redis因为任何原因没有正确关闭而停止工作,你就得做好最近几分钟数据丢失的准备了。

2.RDB需要经常调用fork()子进程来持久化到磁盘。如果数据集很大的话,fork()比较耗时,结果就是,当数据集非常大并且CPU性能不够强大的话,Redis会停止服务客户端几毫秒甚至一秒。AOF也需要fork(),但是你可以调整多久频率重写日志而不会有损(trade-off)持久性(durability)。

5)RDB模式优缺点总结

1.优点:速度快,适合于用作备份,主从复制也是基于RDB持久化功能实现的。

2.缺点:会有数据丢失、导致服务停止几秒

4.AOF持久化

AOF(append only file)只追加文件,记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 
AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。

1)配置AOF持久化

#修改配置文件
[root@db01 redis]# vim /service/redis/6379/redis.conf
#是否打开AOF日志功能
appendonly yes/no
#每一条命令都立即同步到AOF
appendfsync always
#每秒写一次
appendfsync everysec
#写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到AOF
appendfsync no

2)AOF模式的优点

1.使用AOF Redis会更具有可持久性(durable):你可以有很多不同的fsync策略:没有fsync,每秒fsync,每次请求时fsync。使用默认的每秒fsync策略,写性能也仍然很不错(fsync是由后台线程完成的,主线程继续努力地执行写请求),即便你也就仅仅只损失一秒钟的写数据。

2.AOF日志是一个追加文件,所以不需要定位,在断电时也没有损坏问题。即使由于某种原因文件末尾是一个写到一半的命令(磁盘满或者其他原因),redis-check-aof工具也可以很轻易的修复。

3.当AOF文件变得很大时,Redis会自动在后台进行重写。重写是绝对安全的,因为Redis继续往旧的文件中追加,使用创建当前数据集所需的最小操作集合来创建一个全新的文件,一旦第二个文件创建完毕,Redis就会切换这两个文件,并开始往新文件追加。

4.AOF文件里面包含一个接一个的操作,以易于理解和解析的格式存储。你也可以轻易的导出一个AOF文件。例如,即使你不小心错误地使用FLUSHALL命令清空一切,如果此时并没有执行重写,你仍然可以保存你的数据集,你只要停止服务器,删除最后一条命令,然后重启Redis就可以。

3)AOF重写功能

1.因为 AOF 的运作方式是不断地将命令追加到文件的末尾,所以随着写入命令的不断增加, AOF 文件的体积也变得越来越大。举个例子,如果你对一个计数器调用了 100 次 INCR ,那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录。然而在实际上,只使用一条 SET 命令已经足以保存计数器的当前值了,其余 99 条记录实际上都是多余的。

2.为了处理这种情况, Redis 支持一种有趣的特性:可以在不断服务客户端的情况下,对 AOF 文件进行重建。执行 BGREWRITEAOF 命令, Redis 将生产一个新的 AOF 文件,这个文件包含重建当前数据集所需的最少命令。

4)AOF持久化缺点

1.对同样的数据集,AOF文件通常要大于等价的RDB文件。

2.AOF可能比RDB慢,这取决于准确的fsync策略。通常fsync设置为每秒一次的话性能仍然很高,如果关闭fsync,即使在很高的负载下也和RDB一样的快。不过,即使在很大的写负载情况下,RDB还是能提供能好的最大延迟保证。

3.在过去,我们经历了一些针对特殊命令(例如,像BRPOPLPUSH这样的阻塞命令)的罕见bug,导致在数据加载时无法恢复到保存时的样子。这些bug很罕见,我们也在测试套件中进行了测试,自动随机创造复杂的数据集,然后加载它们以检查一切是否正常,但是,这类bug几乎不可能出现在RDB持久化中。为了说得更清楚一点:Redis AOF是通过递增地更新一个已经存在的状态,像MySQL或者MongoDB一样,而RDB快照是一次又一次地从头开始创造一切,概念上更健壮。

1)要注意Redis每次重写AOF时都是以当前数据集中的真实数据从头开始,相对于一直追加的AOF文件(或者一次重写读取老的AOF文件而不是读内存中的数据)对bug的免疫力更强。

2)我们还没有收到一份用户在真实世界中检测到崩溃的报告。

5)AOF持久化优缺点总结

优点:可以最大程度保证数据不丢失
缺点:日志记录量级比较大

5.RDB与AOF

1)应该应用哪一个

1.一般来说,如果想达到足以媲美 PostgreSQL 的数据安全性,你应该同时使用两种持久化功能。

2.如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失,那么你可以只使用RDB持久化。

3.有很多用户单独使用AOF,但是我们并不鼓励这样,因为时常进行RDB快照非常方便于数据库备份,启动速度也比较快,还避免了AOF引擎的bug。

4.个人感触:在企业中,通常都使用RDB来做持久化,因为一般redis是在做MySQL的缓存,就算缓存数据丢失,真实的数据还是在MySQL中,之所以用缓存是为了速度,性能而考虑,所以还是建议使用RDB持久化,相对来说会好一些,除非专门用redis来做一个key:value的数据库,而且数据很重要,那么可以考虑使用AOF

2)RDB与AOF相互作用

1.在版本号大于等于2.4的Redis中,BGSAVE 执行的过程中,不可以执行 BGRWRITEAOF,反过来说,在 BGRWRITEAOF 执行的过程中,也不可以执行 BGSAVE 。

2.这可以防止两个 Redis 后台进程同时对磁盘进行大量的 I/O 操作。如果 BGSAVE 正在执行,并且用户显示地调用 BGRWRITEAOF 命令,那么服务器将向用户回复一个 OK 状态,并告知用户,BGRWRITEAOF 已经被预定执行;一旦 BGSAVE 执行完毕, BGRWRITEAOF 就会正式开始。

3.当 Redis 启动时,如果 RDB 持久化和 AOF 持久化都被打开了,那么程序会优先使用 AOF 文件来恢复数据集,因为 AOF 文件所保存的数据通常是最完整的。

3)备份Redis数据

1.Redis 对于数据备份是非常友好的,因为你可以在服务器运行的时候对 RDB 文件进行复制: RDB 文件一旦被创建,就不会进行任何修改。

2.当服务器要创建一个新的 RDB 文件时,它先将文件的内容保存在一个临时文件里面,当临时文件写入完毕时,程序才使用临时文件替换原来的 RDB 文件。

3.这也就是说,无论何时, 复制 RDB 文件都是绝对安全的。

#以下是我们的建议:
1.创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。

2.确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。

3.至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。

4)RDB持久化高级配置

#编辑配置文件
[root@db01 redis]# vim /etc/redis/6379/redis.conf
-------------
#后台备份进程出错时,主进程停不停止写入? 主进程不停止容易造成数据不一致
stop-writes-on-bgsave-error yes
#导出的rdb文件是否压缩 如果rdb的大小很大的话建议这么做
rdbcompression yes
#导入rbd恢复时数据时,要不要检验rdb的完整性 验证版本是不是一致,会影响导入的速度。
rdbchecksum yes

5)AOF持久化高级配置

#编辑配置文件
[root@db01 redis]# vim /etc/redis/6379/redis.conf
--------------
#正在导出rdb快照的过程中,要不要停止同步aof
no-appendfsync-on-rewrite yes
#aof文件大小比起上次重写时的大小,增长率100%时重写,缺点:业务开始的时候,会重复重写多次
auto-aof-rewrite-percentage 100
#aof文件,至少超过64M时,重写
auto-aof-rewrite-min-size 64mb

七、常用概念

1. 缓存穿透

  • 概念
    访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量大时DB会挂掉。

  • 解决方案
    采用布隆过滤器,使用一个足够大的bitmap,用于存储可能访问的key,不存在的key直接被过滤;
    访问key未在DB查询到值,也将空值写进缓存,但可以设置较短过期时间。

2. 缓存雪崩

  • 概念
    大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。

  • 解决方案
    可以给缓存设置过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效。

3. 缓存击穿

  • 概念
    一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。
  • 解决方案
    在访问key之前,采用SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key。
Copyright © 2009 - Now . XPBag.com . All rights Reserved.
夜心的小站 » Redis 配置教程 常用命令 持久化 缓存问题

提供最优质的资源集合

立即查看 了解详情