Redis是一款,ANSI C语言编写的,高级键值(key-value)缓存和支持永久存储NoSQL数据库产品。
支持多种(5种)数据类型:string,hash,list,set,zset。
功能:
高速读写,数据类型丰富,支持持久化,多种内存分配和回收策略,支持事务,消息队列、消息订阅,支持高可用,支持分布式集群。
企业缓存数据库解决方案
Memcached、Redis、Tair(淘宝缓存)
Memcached:多核的缓存服务,更加适合于多用户并发访问(访问次数少的应用场景)
Redis:单核的缓存服务,在单节点情况下,更加适合少量用户,多次访问的场景
Redis单机安装部署
## 先安装编译软件[root@docker02 ~]# yum install gcc[root@docker02 ~]# mkdir data/redis -p[root@docker02 ~]# cd data/redis[root@docker02 redis]# wget http://download.redis.io/releases/redis-5.0.2.tar.gz[root@docker02 redis]# tar xf redis-5.0.2.tar.gz[root@docker02 redis]# ln -s redis-5.0.2 redis[root@docker02 redis]# lltotal 1912lrwxrwxrwx 1 root root 11 Apr 17 17:02 redis -> redis-5.0.2drwxrwxr-x 6 root root 4096 Nov 22 2018 redis-5.0.2-rw-r--r-- 1 root root 1952989 Nov 22 2018 redis-5.0.2.tar.gz[root@docker02 redis]# cd redis## 编译[root@docker02 redis]# make## 添加环境变量## 此处填写的是本机redis-server的安装路径[root@docker02 ~]# cat etc/profile.d/redis.shexport PATH="/data/redis/redis/src:$PATH"## 刷新新增的环境变量[root@docker02 ~]# source etc/profile.d/redis.sh
redis的基本配置
[root@docker02 ~]# mkdir data/redis/6379/logs -p[root@docker02 ~]# cd data/redis/6379/[root@docker02 6379]# cat redis.confdaemonize yespidfile /data/redis/6379/redis-6379.pidport 6379bind 127.0.0.1timeout 300loglevel noticelogfile /data/redis/6379/logs/redis-6379.logsyslog-enabled nodatabases 16requirepass redis.123
### redis配置文件详解daemonize yes #是否以后台进程运行pidfile var/run/redis/redis-server.pid #pid文件位置port 6379 #监听端口bind 127.0.0.1 #绑定地址,如外网需要连接,设置0.0.0.0,多个使用空格timeout 300 #连接超时时间,单位秒loglevel notice #日志级别,分别有:# debug :适用于开发和测试# verbose :更详细信息# notice :适用于生产环境# warning :只记录警告或错误信息logfile var/log/redis/redis-server.log #日志文件位置syslog-enabled no #是否将日志输出到系统日志databases 16#设置数据库数量,默认数据库为0############### 快照方式 ###############save 900 1 #在900s(15m)之后,至少有1个key发生变化,则快照save 300 10 #在300s(5m)之后,至少有10个key发生变化,则快照save 60 10000 #在60s(1m)之后,至少有1000个key发生变化,则快照rdbcompression yes #dump时是否压缩数据dir var/lib/redis #数据库(dump.rdb)文件存放目录############### 主从复制 ###############slaveof <masterip> <masterport> #主从复制使用,用于本机redis作为slave去连接主redismasterauth <master-password> #当master设置密码认证,slave用此选项指定master认证密码slave-serve-stale-data yes #当slave与master之间的连接断开或slave正在与master进行数据同步时,如果有slave请求,当设置为yes时,slave仍然响应请求,此时可能有问题,如果设置no时,slave会返回"SYNC with master in progress"错误信息。但INFO和SLAVEOF命令除外。############### 安全 ###############requirepass foobared #配置redis连接认证密码############### 限制 ###############maxclients 128#设置最大连接数,0为不限制maxmemory <bytes>#内存清理策略,如果达到此值,将采取以下动作:# volatile-lru :默认策略,只对设置过期时间的key进行LRU算法删除# allkeys-lru :删除不经常使用的key# volatile-random :随机删除即将过期的key# allkeys-random :随机删除一个key# volatile-ttl :删除即将过期的key# noeviction :不过期,写操作返回报错maxmemory-policy volatile-lru#如果达到maxmemory值,采用此策略maxmemory-samples 3 #默认随机选择3个key,从中淘汰最不经常用的############### 附加模式 ###############appendonly no #AOF持久化,是否记录更新操作日志,默认redis是异步(快照)把数据写入本地磁盘appendfilename appendonly.aof #指定更新日志文件名# AOF持久化三种同步策略:# appendfsync always #每次有数据发生变化时都会写入appendonly.aof# appendfsync everysec #默认方式,每秒同步一次到appendonly.aof# appendfsync no #不同步,数据不会持久化no-appendfsync-on-rewrite no #当AOF日志文件即将增长到指定百分比时,redis通过调用BGREWRITEAOF是否自动重写AOF日志文件。############### 虚拟内存 ###############vm-enabled no #是否启用虚拟内存机制,虚拟内存机将数据分页存放,把很少访问的页放到swap上,内存占用多,最好关闭虚拟内存vm-swap-file var/lib/redis/redis.swap #虚拟内存文件位置vm-max-memory 0 #redis使用的最大内存上限,保护redis不会因过多使用物理内存影响性能vm-page-size 32 #每个页面的大小为32字节vm-pages 134217728 #设置swap文件中页面数量vm-max-threads 4 #访问swap文件的线程数############### 高级配置 ###############hash-max-zipmap-entries 512 #哈希表中元素(条目)总个数不超过设定数量时,采用线性紧凑格式存储来节省空间hash-max-zipmap-value 64 #哈希表中每个value的长度不超过多少字节时,采用线性紧凑格式存储来节省空间list-max-ziplist-entries 512 #list数据类型多少节点以下会采用去指针的紧凑存储格式list-max-ziplist-value 64 #list数据类型节点值大小小于多少字节会采用紧凑存储格式set-max-intset-entries 512 #set数据类型内部数据如果全部是数值型,且包含多少节点以下会采用紧凑格式存储activerehashing yes #是否激活重置哈希
启动redis-server
## 上一步的刷新环境变量后,就可以在任意目录下使用redis的命令[root@docker02 ~]# redis-server data/redis/6379/redis.conf[root@docker02 ~]# ps -ef|grep 'redis'root 5447 1 0 11:07 ? 00:00:00 redis-server 127.0.0.1:6379
验证redis-server
[root@docker02 ~]# redis-cli -h 127.0.0.1 ## 登陆,默认6379127.0.0.1:6379> auth redis.123 ## 密码验证OK127.0.0.1:6379> keys * ## 查看keys值(empty list or set)
Redis单机多实例安装部署
## 同一台主机启动一个端口号为6380的redis-server[root@docker02 ~]# mkdir data/redis/6380/logs -p[root@docker02 ~]# cat data/redis/6380/redis.confdaemonize yespidfile data/redis/6380/redis-6380.pidport 6380bind 127.0.0.1timeout 300loglevel noticelogfile data/redis/6380/logs/redis-6380.logsyslog-enabled nodatabases 16requirepass redis.456[root@docker02 ~]# redis-server data/redis/6380/redis.conf[root@docker02 logs]# ps -ef|grep 'redis'root 5447 1 0 11:07 ? 00:00:00 redis-server 127.0.0.1:6379root 7830 1 0 11:15 ? 00:00:00 redis-server 127.0.0.1:6380[root@docker02 6380]# redis-server data/redis/6380/redis.conf[root@docker02 6380]# redis-cli -h 127.0.0.1 -p 6380127.0.0.1:6380> auth redis.456OK127.0.0.1:6380> keys *(empty list or set)## 同一台主机启动一个端口号为6381的redis-server[root@docker02 ~]# mkdir data/redis/6381/logs -p[root@docker02 ~]# cat data/redis/6381/redis.confdaemonize yespidfile data/redis/6381/redis-6381.pidport 6381bind 127.0.0.1timeout 300loglevel noticelogfile data/redis/6381/logs/redis-6381.logsyslog-enabled nodatabases 16requirepass redis.789[root@docker02 ~]# redis-server data/redis/6381/redis.conf[root@docker02 6380]# ps -ef|grep 'redis'root 5447 1 0 11:07 ? 00:00:00 redis-server 127.0.0.1:6379root 8507 1 0 11:17 ? 00:00:00 redis-server 127.0.0.1:6380root 9096 1 0 11:19 ? 00:00:00 redis-server 127.0.0.1:6381[root@docker02 ~]# redis-cli -h 127.0.0.1 -p 6381127.0.0.1:6381> auth redis.789OK127.0.0.1:6381> keys *(empty list or set)
RDB持久化介绍
什么是持久化:
持久化:就是将内存中的数据,写入到磁盘上,并且是永久存在的。
可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)
RDB持久化的优点:
RDB是一种表示某个即时点的Redis数据的紧凑文件。RDB文件适用于备份。例如,你可能想要将每小时归档24小时的RDB文件,每天保存近30天的RDB快照。这允许你很容易的恢复不同版本的数据集以容灾。
RDB非常适合于灾难恢复,作为一个紧凑的单一文件,可以被传输到远程的数据中心。
RDB最大化了Redis的性能,因为Redis父进程持久化时唯一需要做的是启动(fork)一个子进程,由子进程完成所有剩余工作。父进程实例不需要执行像磁盘IO这样的操作。
RDB在重启保存了大数据集的实例时比AOF要快。
RDB持久化的缺点:
当你需要在Redis停止工作(例如停电)时最小化数据丢失,RDB可能不太好。你可以配置不同的保存点(save point)来保存RDB文件(例如,至少5分钟保存一次或者对数据集第100次写入后,当然也可以设置其他保存时间)。然而,你通常每隔5分钟或更久创建一个RDB快照,所以一旦Redis因为任何原因没有正确关闭而停止工作,你就要做好最近几分钟数据丢失的准备了。
RDB需要经常调用fork()子进程来持久化到磁盘。如果数据集很大的话,fork()比较耗时,结果就是,当数据集非常大并且CPU性能不够强大的话,Redis会停止服务客户端几毫秒甚至一秒。AOF也需要fork(),但是你可以调整多久频率重写日志而不会有损(trade-off)持久性(durability)。
RDB持久化的优缺点总结:
优点:速度快,适合于用作备份,主从复制也是基于RDB持久化功能实现的。
缺点:会有数据丢失,导致服务停止几秒。
RDB持久化核心配置文件:
[root@docker02 ~]# cat /data/redis/6379/redis.conf...## 持久化数据文件存储位置dir /data/redis/6379/rdb## rdb持久化数据文件名dbfilename dump.rdb#900秒(15分钟)内有1个更改save 900 1#300秒(5分钟)内有10个更改save 300 10#60秒(1分钟)内有10000个更改save 60 10000...
AOF持久化介绍
AOF(append only file)只追加文件,记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF文件中的命令全部以Redis协议的格式来保存,新命令会被追加到文件的末尾。
AOF持久化优点:
使用AOF Redis会更具有可持续性(durable):你可以有很多不同的fsync策略:没有fsync,每秒fsync,每次请求时fsync。使用默认的每秒fsync策略,写性能也仍然很不错(fsync是由后台线程完成的,主线程继续努力地执行写请求),即便你也就仅仅只损失一秒钟的写数据。
AOF日志是一个追加文件,所以不需要定位,在断电时也没有损坏问题。即使由于某种原因文件末尾是一个写到一半的命令(磁盘满或者其他原因),redis-check-aof工具也可以很轻易的修复。
当AOF文件变得很大时,Redis会自动在后台进行重写。重写是绝对安全的,因为Redis继续往旧的文件中追加,使用创建当前数据集所需的最小操作集合来创建一个全新的文件,一旦第二个文件创建完毕,Redis就会切换这两个文件,并开始往新文件追加。
AOF文件里面包含一个接一个的操作,以易于理解和解析的格式存储。你也可以轻易的导出一个AOF文件。例如,即使你不小心错误地使用FLUSHALL命令清空一切,如果此时并没有执行重写,你仍然可以保存你的数据集,你只要停止服务器,删除最后一条命令,然后重启Redis就可以。
AOF持久化缺点:
对于同样的数据集,AOF文件通常要大于等价的RDB文件
AOF可能比RDB慢,这取决于准确的fsync策略。通常fsync设置为每秒一次的话性能仍然很高,如果关闭fsync,即使在很高的负载下也和RDB一样的快。不过,即使在很大的写负载情况下,RDB还是能提供能好的最大延迟保证。
在过去,我们经历了一些针对特殊命令(例如,像BRPOPLPUSH这样的阻塞命令)的罕见bug,导致在数据加载时无法恢复到保存时的样子。这些bug很罕见,我们也在测试套件中进行了测试,自动随机创造复杂的数据集,然后加载它们以检查一切是否正常,但是,这类bug几乎不可能出现在RDB持久化中。为了说得更清楚一点:Redis AOF是通过递增地更新一个已经存在的状态,像MySQL或者MongoDB一样,而RDB快照是一次又一次地从头开始创造一切,概念上更健壮。但是,1)要注意Redis每次重写AOF时都是以当前数据集中的真实数据从头开始,相对于一直追加的AOF文件(或者一次重写读取老的AOF文件而不是读内存中的数据)对bug的免疫力更强。2)我们还没有收到一份用户在真实世界中检测到崩溃的报告。
AOF持久化优缺点总结
优点:可以最大程度保证数据不丢失
缺点:日志记录量级比较大
AOF持久化核心配置参数
[root@db01 redis]# cat /data/redis/6379/redis.conf...## 是否打开AOF日志功能appendonly yes/no## 每一条命令都立即同步到AOFappendfsync always## 每秒写一次appendfsync everysec## 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到AOFappendfsync no...
RDB 和 AOF,选型
一般来说,如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
有很多用户单独使用AOF,但是我们并不鼓励这样,因为时常进行RDB快照非常方便于数据库备份,启动速度也较之快,还避免了AOF引擎的bug。
个人感触:在企业中,通常都使用RDB来做持久化,因为一般redis是在做MySQL的缓存,就算缓存数据丢失,真实的数据还是在MySQL中,之所以用缓存是为了速度,性能而考虑,所以还是建议使用RDB持久化,相对来说会好一些,除非专门用redis来做一个key:value的数据库,而且数据很重要,那么可以考虑使用AOF。
RDB快照的工作方式
默认情况下,Redis保存数据集快照到磁盘,名为dump.rdb的二进制文件。你可以设置让Redis在N秒内至少有M次数据集改动时保存数据集,或者你也可以手动调用SAVE或者BGSAVE命令。
在上文中我们已经在配置文件中做过对应的配置:例如,这个配置会让Redis在每个60秒内至少有1000次键改动时自动转储数据集到磁盘:save 60 1000
当 Redis 需要保存 dump.rdb 文件时,服务器执行以下操作:
Redis 调用 fork() ,同时拥有父进程和子进程。子进程将数据集写入到一个临时的RDB 文件中。当子进程完成对新 RDB 文件的写入时, Redis 用新RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
这种方式使得 Redis 可以从写时复制机制中获益
AOF重写功能介绍
因为 AOF 的运作方式是不断地将命令追加到文件的末尾,所以随着写入命令的不断增加, AOF 文件的体积也变得越来越大。举个例子,如果你对一个计数器调用了 100 次 INCR ,那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录。然而在实际上,只使用一条 SET 命令已经足以保存计数器的当前值了,其余 99 条记录实际上都是多余的。
为了处理这种情况, Redis 支持一种有趣的特性:可以在不断服务客户端的情况下,对 AOF 文件进行重建。执行 BGREWRITEAOF 命令, Redis 将生产一个新的 AOF 文件,这个文件包含重建当前数据集所需的最少命令。
AOF有多持久
你可以配置 Redis 多久才将数据 fsync 到磁盘一次。
有三个选项:每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。
每秒 fsync 一次:足够快(和使用 RDB 持久化差不多,)并且在故障时只会丢失1秒钟的数据。
从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。
推荐(并且也是默认)的措施为每秒 fsync 一次,这种 fsync 策略可以兼顾速度和安全性。
总是 fsync 的策略在实际使用中非常慢,即使在 Redis2.0 对相关的程序进行了改进之后仍是如此。频繁调用 fsync 注定了这种策略不可能快得起来。
备份Redis数据
Redis 对于数据备份是非常友好的,因为你可以在服务器运行的时候对 RDB 文件进行复制:RDB 文件一旦被创建,就不会进行任何修改。
当服务器要创建一个新的 RDB 文件时,它先将文件的内容保存在一个临时文件里面,当临时文件写入完毕时,程序才使用临时文件替换原来的 RDB 文件。
这也就是说,无论何时, 复制 RDB 文件都是绝对安全的。
以下是我们的建议:
1)创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。
2)确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照:比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。
3)至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。
RDB持久化高级配置
[root@db01 redis]# cat /data/redis/6379/redis.conf...## 后台备份进程出错时,主进程停不停止写入? 主进程不停止容易造成数据不一致stop-writes-on-bgsave-error yes## 导出的rdb文件是否压缩 如果rdb的大小很大的话建议这么做rdbcompression yes## 导入rbd恢复时数据时,要不要检验rdb的完整性 验证版本是不是一致rdbchecksum yes...
AOF持久化高级配置
[root@db01 redis]# cat /data/redis/6379/redis.conf...## 正在导出rdb快照的过程中,要不要停止同步aofno-appendfsync-on-rewrite yes/no#aof文件大小比起上次重写时的大小,增长率100%时重写,缺点:业务开始的时候,会重复重写多次auto-aof-rewrite-percentage 100## aof文件,至少超过64M时,重写auto-aof-rewrite-min-size 64mb...




