1.介绍
特点:
1.是一个键值存储和数据结构存储的NOSQL。
支持数据结构有:string、hashes、lists、sets、sorted sets、bitmaps、hyperloglogs
支持的存储方式有:异步快照、AOF(Append Only File)也就是追加到文件
2.支持LUA脚本的服务器端编程
3.单进程单线程工作模型
实际测试结果:
100万小键-值使用100M内存
单线程支持50万并发请求
高性能和高可用方案:
1.支持主从模式(借助sentinel实现HA)
支持主读写、从只读
支持消息队列,也就是发布/订阅方式
2.支持集群(3.0开始)
相对memcached的优势:
丰富的对数据结构的操作:string、hashes、lists、sets、sorted sets、bitmaps、hyperloglogs
内建数据复制和集群等方案特性
就地更新
持久化,避免雪崩效应
Redis在存储中的位置:
1.存储系统:
RDBMS关系型:Oracle、MySQL、SQL Server、DB2、PostgreSQL
NoSQL非关系:Cassandra、HBase、Memcached、MongoDB、Redis
NewSQL:Aerospike...
2.NoSQL的分类:
键值:Memcached、Redis,...
列式:Cassandra、HBase,...
文档:MongoDB,...
图式:Neo4j...
Redis工具
1.服务端、客户端以及性能压测
redis-server
redis-cli
redis-banchmark
2.文件持久化检查工具
redis-check-dump 检查RDB快照
redis-check-aof 检查AOF文件
2.安装
包来源:
源码包:http://www.redis.io/download
rpm包:https://pkgs.org/
安装rpm包:
1.安装jemalloc依赖包所存放的库
rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
2.本地安装redis
yum -y localinstall redis-3.0.7-4.el6.art.x86_64.rpm
3.配置
GENERAL部分:
daemonize no
pidfile /var/run/redis/redis.pid
port 6379
tcp-backlog 511
bind 127.0.0.1
loglevel notice
logfile /var/log/redis/redis.log
databases 16
daemonize:no表示前台进程方式运行,但是脚本启动时会以后台进程运行redis
tcp-backlog:TCP请求满了后,空出多大的队列缓存未处理的请求
bind :可以同时绑定多个IP,用空格隔开
databases:在集群环境中只支持0号数据库
SNAPSHOTTING部分:
save 900 1
save 300 10
save 60 10000
dbfilename "dump.rdb"
dir "/var/lib/redis/1"
save 900 1 :900秒内有1个键发生变化就做快照
save 300 10 :300秒内有10个键发生变化就做快照
save 60 10000 :60秒内有10000个键发生变化就做快照
或者
save "" 不做快照
dbfilename :数据文件名称
dir :数据文件目录
REPLICATION部分:
# slaveof <masterip> <masterport>
# masterauth <master-password>
slave-priority 100
slaveof :作为从节点时,指定主节点信息
masterauth :如果主节点需要密码认证,在这里填写
slave-priority:从节点的优先级,0表示最低优先级
SECURITY部分:
requirepass redis
requirepass :操作需要密码认证
LIMITS部分:
# maxclients 10000
# maxmemory <bytes>
maxclients :最大客户端并发数
maxmemory :最大使用内存限制
APPEND ONLY MODE部分:
appendonly no
appendfilename "appendonly.aof"
LUA SCRIPTING部分:
略
REDIS CLUSTER部分:集群
略
SLOW LOG部分:慢查询
略
LATENCY MONITOR部分:
略
EVENT NOTIFICATION部分:与发布订阅相关
略
ADVANCED CONFIG部分:
略
4.基本管理
启动和关闭
service redis start|stop
获取帮助:
1.登录前
redis-cli -h
2.登录后
172.16.0.7:6379> help <tab>
172.16.0.7:6379> help @string 查看某组所有可用操作
172.16.0.7:6379> help @server 查看可动态修改的服务器配置
登录和登出:
redis-cli -h 172.16.0.7
172.16.0.7:6379> quit
打开数据库(名称空间):
172.16.0.7:6379> select 1
select n:n表示被打开的第n个数据库,其中0表示默认数据库
注意:在分布式场景下,redis只支持一个库,如果需要分别存储论坛、博客和商城的键值,用bbs_、blog和shop来分开
各类数据对象的操作命令
@string
SET disto fedora
SETNX disto centos
SETXX foo redhat
GET disto
APPEND disto ",centos"
STRLEN disto
EXISTS disto
说明:
SET:SET key value [EX seconds] [PX milliseconds] [NX|XX]。
EX seconds:设置key的过时时间,单位为秒。
PX milliseconds:设置key的过期时间,单位为毫秒。
NX:(if Not eXist)只有键key不存在的时候才会设置key的值
XX:只有键key存在的时候才会设置key的值
这几个命令表示三类设置字串的方式,获取字串值,追加字串值,计算字串值长度,判断字串值是否存在等
对数字类的字符串可以
SET count 0
INCR count
DECR count
三个命令表示设置count为0,自增1,自减1
@list 列表,形式如[A,B,C,D]
LPUSH week mon
LPUSH week sun
RPUSH week tue
LSET week 1 MON
LINDEX week 1
LPOP week
RPOP week
这些例子说明对week数组的创建、左插入元素、右插入元素、修改元素内容、查看元素值、弹出左侧元素、弹出右侧元素
@set ,形式如{A,B,C,D}
SADD week1 mon tue wed thu fri
SADD week2 fri sat sun
SINTER week1 week2
SUNION week1 week2
SPOP week1
SISMEMBER week1 mon
创建set集合、求交集、求并集、随机弹出、是否存在元素
@sorted_set {A:1,B:2,C:3,D:4}
ZADD weekday 2 tue 1 mon 3 wed
ZCARD weekday
ZRANK weekday tue
ZSCORE weekday tue
ZRANGE weekday 0 2
新建一个排序集合,求集合个数,求元素按score排序后的索引,求元素的score,求索引范围内的元素
@hash {field1:"a",field2:"b"}
HSET myWeek mon monday
HSET myWeek tue tuesday
HGET myWeek mon
HKEYS myWeek
HVALS myWeek
HLEN myWeek
HDEL myWeek tue
新建字典、获取字段元素、获取key列表、获取值列表、获取元素个数、删除元素
@connection相关命令
AUTH
PING
ECHO
QUIT
SELECT
@server 服务器配置
--设置客户端名称,杀掉客户端
CLIENT SETNAME "172.16.0.7"
CLIENT GETNAME
CLIENT KILL IP:PORT
--重置指令info [Server|Clients|...]的信息
CONFIG RESETSTAT
--运行时修改指定配置参数并同步到配置文件
CONFIG GET $PARAM
CONFIG SET $PARAM $VALUE
CONFIG REWRITE
--查看当前库的键数量
DBSIZE
--保存数据到磁盘
BGSAVE 异步保存数据到磁盘
SAVE 同步保存数据到磁盘
LASTSAVE 返回上次同步时间
--主从复制
SLAVEOF host port
SYNC
--监控命令执行
MONITOR
@pubsub 发布与订阅
有多种方式,包含1对多,多对1,多对多
1对1时
A:SUBSCRIBE new
B:PUBLISH new "hello"
多对1时
A:PSUBSCRIBE "new.i[to]"
B:PUBLISH new.it "amd"
PUBLISH new.io "disk"
适合全体类型的命令:
EXISTS(key):确认key是否存在
TYPE(key):得到key的类型
DEL(key):删除一个key
KEYS(pattern):返回给定patten的所有key
RENAME(oldname,newname):key的重命名
DBSIZE:返回当前库的key数目
EXPIRE(key,ttl):设定key的生存时间
TTL(key):获得key的生存时间
MOVE(key,dbindex):将当前库的key移动到别的库
FLUSHDB:清空当前库
FLASHALL:清空所有库
重点在最后两个命令
5.使用场景:
实现单机密码认证
修改redis.conf,设置requirepass $pass
登录redis后,使用AUTH $pass认证
支持事务
事务会将任务操作打包,并且执行开始时阻塞其他客户端的操作,直至执行完成,另外,其不支持回滚操作。
WATCH ip
MULTI
SET ip 192.168.68.7
SET port 8080
EXEC
说明:
MULTI:启动事务
EXEC:执行事务
WATCH:在EXEC命令执行前用于监视指定数量的键,如果键发生改变,则服务器拒绝执行事务
Redis的持久化命令和配置
RDB:快照,按事先策略周期保存数据到二进制文件中,默认文件为dump.rdb
AOF:将更改操作保存到文件,
拿Mysql做对比,RDB相当于MySQL的周期性备份,而AOF相当于MySQL的binlog。
手动写入RDB需要使用命令:SAVE和BGSAVE。其中的SAVE在执行时会阻塞所有客户端请求。
手动写入AOF需要使用命令:BGREWRITEAOF。将内存中的数据以命令方式写入临时文件,完成后替换原来的AOF文件。
RDB的配置
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis/
save ""表示关闭RDB功能
AOF的配置
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
appendfsync:always表示每次修改都同步,everysec每秒都同步,no表示由内核决定何时同步
auto-aof-rewrite-percentage:100表示当前AOF是上次重写时AOF的两倍,则rewrite。
auto-aof-rewrite-min-size:64mb表示超过64M才rewrite,限制文件小时的重写次数。
RDB与AOF同时使用时:
BGSAVE和BGREWRITEAOF不会同时执行
在Redis服务器启动用于恢复时,优先使用AOF
Redis的复制
模式:
一个Master可以有多个Slave
一个Slave可以是其他Slave的Slave
同步过程:
Slave向Master发送sync请求同步数据,Master启动子进程将快照保存到本地数据文件中,然后发送数据文件给Slave,Slave收到文件保存到本地数据文件后,加载文件到内存,实现数据库复制。
关于密码认证:
如果主服务器设置了requirepass $pass,则从服务器需要对应设置masterauth $pass
配置过程
1.主服务器端配置:
requirepass redis #密码认证,可选
2.从服务器配置:
# redis-cli -h 172.16.0.6
>FLUSHALL
>CONFIG SET masterauth redis
>SLAVEOF 172.16.0.7 6379
>KEYS *
>INFO
登录从服务器后清空数据,设置主服务器认证密码,连接主服务器,查看同步数据结果
3.在主服务器查看从库信息
>AUTH redis
>INFO
sentinel
场景:
一主三从,如果主节点离线了,sentinel根据主节点上的多个从节点来选择提升某个从节点为主节点,并且告诉客户端新的主节点是哪一个。
sentinel用于管理多个redis服务器,实现高可用:
监控主节点
通知
自动故障转移
centinal进程之间通讯使用的协议:
留言协议:接收主服务器是否下线的消息
投票:是否执行故障迁移,选择哪一个从服务器成为主服务器
主观下线和客观下线:
主观下线:一个sentinel实例判断出节点下线。
客观下线:多个sentinel节点协商后判断节点下线。
一个sentinel通过给主、从节点以及其他sentinel节点发送PING请求,达到检测心跳信息
使用步骤:
sentinel 服务器自身初始化
使用指定配置文件,初始化监控的主服务器列表
创建到主服务器的连接
配置centinel:/etc/redis-sentinel.conf
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
第二行:指定被监控的主节点的名字、IP和端口,以及投票数(值大于centinal节点数的一半,例如这里为2,表示有3个sentinel节点)。
第三行:30秒内主节点没反应,认为其已经下线。
第四行:从节点替换主节点的故障转移过程中,允许多少个其他从节点与其同步用于客户端查询,默认允许1一个从节点同步
第五行:指定故障转移的超时时间,默认为3分钟
启动sentinel,两种方式
redis-server /etc/sentinel.conf --sentinel
redis-sentinel
sentinel管理命令:
SENTINEL masters
SENTINEL slaves <master name>
SENTINEL get-master-addr-by-name <master name>
SENTINEL reset
SENTINEL failover <master name>
Clustering:
通过数据库分片实现分布式数据库,每个clustering节点仅是数据库的一部分
去中心化的,也就是每个clustering节点可以处理客户端请求。每个节点具有全局元数据列表,显示哪个键映射到哪个节点。
类似方案:
Twemproxy(Twitter)
Codis(豌豆荚,豆瓣的)
http://www.cnblogs.com/xuanzhi201111/p/4425194.html
http://www.open-open.com/lib/view/open1436360508098.html
Redis Cluster(官方)
Cerberus(芒果TV)
6.redis的高可用
使用三个主从节点,以及三个sentinel实现redis的高可用
在一台物理主机准备3个redis节点:
H1(主):172.16.0.7:6379
H2(从):172.16.0.7:6380
H3(从):172.16.0.7:6381
注意:每个节点使用不同的配置文件来启动,配置中除了进程方式、IP相同外,端口、进程ID文件、日志文件、数据文件以及优先级都不能相同,以H1的配置为例,其他类似
# mkdir /etc/redis/ /var/lib/redis/{1..3}/
# chown redis.redis /var/lib/redis/{1..3}/
# cp /etc/redis.conf /etc/redis/redis.conf.1
# cp /etc/redis.conf /etc/redis/redis.conf.2
# cp /etc/redis.conf /etc/redis/redis.conf.3
# vim /etc/redis/redis.conf.1
----------------------------------
daemonize yes
port 6379
bind 172.16.0.7
pidfile /var/run/redis/redis1.pid
logfile /var/log/redis/redis1.log
dir /var/lib/redis/1/
# requirepass <redis-password> 可以指定认证密码,但是实验为了简单,略去
# masterauth <master-password>
slave-priority 100
-----------------------------------
分别启动主、从节点
# redis-server /etc/redis/redis.conf.1
# redis-server /etc/redis/redis.conf.2
# redis-server /etc/redis/redis.conf.3
按这样的方式配置每个从节点
# redis-cli -h 172.16.0.7 -p 6380
172.16.0.7:6380> FLUSHALL
172.16.0.7:6380> SLAVEOF 172.16.0.7 6379
172.16.0.7:6380> KEYS *
在刚才的物理主机上准备3个centinel节点
C1:172.16.0.7:26379
C2:172.16.0.7:26380
C3:172.16.0.7:26381
每个节点使用不同的配置文件来启动,配置中除了IP相同外,端口不能相同
# cp /etc/redis-sentinel.conf /etc/redis/redis-sentinel.conf.1
# cp /etc/redis-sentinel.conf /etc/redis/redis-sentinel.conf.2
# cp /etc/redis-sentinel.conf /etc/redis/redis-sentinel.conf.3
# vim /etc/redis/redis-sentinel.conf.1
-----------------------------------------
port 26379
sentinel monitor mymaster 172.16.0.7 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 60000
------------------------------------------
每个配置文件不同的地方在于第一个配置项
分别启动centinel节点并查看
# redis-server /etc/redis/redis-sentinel.conf.1 --sentinel
# redis-cli -h 172.16.0.7 -p 26379
172.16.0.7:26379> INFO
172.16.0.7:26379> SENTINEL masters
172.16.0.7:26379> SENTINEL slaves mymaster
172.16.0.7:26379> SENTINEL get-master-addr-by-name mymaster
测试主从节点的故障转移:
kill掉主节点的进程,进去任一sentinel,检查查看主节点是否已更换,所有从节点是否包含已被kill的原主节点并且其状态是否为DOWN