redis
一、redis入门介绍
- 入门概述
- 介绍:
Redis: REmote DIctionary Server(远程字典服务器)
是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行,并支持持久化的NoSQL数据库,是当前最热门的nosql数据库之一,也被成为数据结构服务器
redis与其他key-value缓存产品有一下三个特点:
- redis支持数据的持久化次加载进行使用
- redis不仅仅支持简单的key-value类型的数据,同事还提供list,map,set,zset等数据结构的储存
- redis支持数据的备份,即master-slave模式的数据备份
-
- 作用
内存储存和持久化:redis支持异步将内存中的额数据写到硬盘上,同时不影响继续服务
取最新N个数据的操作,如:可以将最新的10条评论的id放在redis的list集合里面
模拟类似于httpSession这种需要设定过期时间的功能
发布、订阅消息系统
定时器、计数器
-
- 下载地址
http://redis.io
http://www.redis.cn
- redis的安装
- 将下载的redis tar文件复制到/opt中 (可自定义)
- 解压tar包 tar -zxvf [redis].tar.gz
- 进入redis目录
- 在redis目录中执行 make 命令
- 运行出现错误安装gcc yum install gcc-c++
- Jemalloc/jemalloc.h 没有那个文件或目录 运行 make distclean 之后再 make
- 执行完make之后继续执行 make install
- 查看默认安装目录: usr/local/bin
- redis-benchmark 性能测试工具
- redis-check-aof 修复有问题的AOF文件
- redis-check-dump 修复有问题的dump.rdb文件
- redis-cli 客户端 操作入口
- redis-sentinel redis集群使用
- redis-server redis服务器启动命令
- 启动
- 修改redis.conf 文件将里面的daemonize no修成yes 让服务在后台启动
- 执行启动命令并制定配置文件 redis-server redis.conf
- 关闭
- 单实例关闭:redis-cli shutdown
- 多实例关闭:制定端口关闭 redis-cli -p 6379 shutdown
- redis启动后基础知识
- 单进程
单进程模型类处理客户端的请求。对读写等时间的响应是通过对epoll函数的包装来做到的。redis的实际处理速度完全依靠主进程的执行效率
epoll是linux内核为处理大批量文件描述符而做了改进的epoll,是linux下多路复用IO接口,select/poll的增强版本,他能显著提高程序在大量并发连接中只有少量活跃的情况下的系统cpu利用率
-
- 默认16个数据库 从0至15 默认使用0号数据库
- select 命令切换数据库
- Dbsize 查看当前数据的key的数量
- Flushdb 清空当前库
- flushall 清空所有库
- 同一密码管理,16个库都是同样的密码
- redis索引都是从零开始
- 默认端口是6379
二、redis数据类型
- redis5种数据类型
- String(字符串)
string是redis最基本的类型,你可以理解成语Memcached一模一样的类型,一个key对应一个value
string类型是二进制安全的,意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象
string类型是redis最基本的数据类型,一个redis中字符串value最多可以是512m
-
- Hash(哈希) java中的map
redis hash 是一个键值对集合
是一个string类型的field和value的映射表,hash特别适用于储存对象
-
- List(列表)
redis 列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边) 顶层实际是一个链表
-
- Set(集合)
redis的set是string类型的无序集合,他是通过hashtable实现的
-
- Zset(有序集合)
redis zset和set一样也是string类型元素的集合,并不允许重复的成员,不同的是每个成员都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序,zset的成员是唯一的。但分数却可以重复
- redis常见数据类型操作命令
- redis键(key)
- 常用
- del key 该命令用户在key存在删除key
- dump key 序列化指定key 并返回被序列化的值
- exists key 检查指定key是否存在
- expire key seconds 为指定可以设置过期时间
- expireat key timestamp expireat的作用和 expire类似,都用于为key设置过期时间,不同在于expireat命令接受的时间参数是unix时间戳
- expire key milliseconds 设置key的过期时间以毫秒计算
- expireat key milliseconds 设置key过期时间的时间戳(毫秒)
- keys pattren 查找符合条件的key
- move key db 当前数据库的key移动给定的数据库db当中
- persist key 移除key的过期时间 key永久有效
- pttl key 以毫秒为档位返回key的过期时间
- ttl key 以秒为单位返回key的过期时间
- randomey 从当前数据库中随机返回一个key
- rename key newkey 修改key的名称
- renamenx key newkey 仅当newkey不出在时 将key改名为newkey
- type key 返回key所储存的值的类型
- 常用
- redis字符串 stirng
- redis列表 list
- redis集合 set
- redis哈希 hash
- redis有序集合zset
三、解析配置文件
- 文件位置
- redis/redis.conf
- units单位
- 配置大小单位,开头定意思了一些基本的度量单位,只支持bytes 不支持bit
- 对大小写不敏感
- includes包含
- 可以通过includes包含 redis.conf可以作为总闸,包含其他
- general通用
- Daemoniz 是否后台启动
- pidfile pid存放文件
- port 端口号
- tcp-backlog
- 设置tcp的backlog,backlog其实是一个连接队列,backlog列队总和=未来三次握手队列+已经完成三次握手队列
- 在高并发环境下你需要一个高backlog值来避免慢客户端连接问题,注意inux内核会将这个值减小到/proc/sys/net/core/somaxcoun的值。所以需要确认增大somaxcoun和tcp_max_syn_backlog两个值来达到想要的效果
- timeout
- bind
- tcp-keepalive
- 单位为秒。如果设置为0,则不会进行keepalive检测,建议设置成60
- loglevel
- logfile
- syslog-enabled
- 是否把日志输出到syslog中
- syslog-ident
- 指定syslog里的日志标志
- syslog-facility
- 指定syslog设备,值可以是user或local0-local7
- databases
- snapshotting快照
- save
- rdb是整个内存的压缩过的snapshot rdb的数据结构可以配置符合的快照出发条件 默认 1分钟改了1万次 或 5分钟改了10万次 或15分钟内改了1次
- 如果想金庸rdb持久化的策略,只要吧设置任何save执行,或者给save传入一个空字符串参数也可以
- stop-writes-on-bgsave-error
- 如果配置成no,表示你吧在乎数据不一致或者有其他的手段和控制
- rdbcompression
- rdbcompression 对于储存到磁盘中的快照,可以设置是否进行压缩存储,如果是的话,redis会采用 lzf算法进行压缩,如果你不想消耗cpu来进行压缩的话,可以设置为关闭此功能
- rdbchecksum
- rdbchecksum 在储存快照后,还可以让redis使用crc64算法来进行数据检验,但是这样会增加大约10%的性能消耗,如果希望获取到最大的行能提升,可以关闭此功能
- dbfilename
- dir
- save
- replication复制
- security安全
- 设置访问密码 命令行链接后通过 auth 授权
- limits限制
- maxclinets
- 设置redis同时可以与多少个客户端进行链接,默认情况下为10000个客户端。当你无法设置进程文件句柄限制时,redis 会设置为当前的文件句柄限制值减去32,因为redis会为自己内部处理逻辑留一些句柄出来。如果达到了此限制,redis则会拒绝新的链接请求,并且向这写请求放发出 max number of clients reached 以作回应
- maxmemory
- 设置redis可以用使用的内存量。一旦到达使用上限,redis将会试图移除内部数据,移除规则可以通过maxmemory-policy来指定,如果redis无法根据移除规则来移除内存中的数据,或者设置了不允许移除,那么redis则会针对那些需要申请内存的指令返回错误信息,比如set lpush等。
- 但是对于无内存申请的指令,人奶会正常响应,比如get等,如果你的redis是主redis (说明你的redis有从redis)那么在设置内存使用上限时,需要在系统中流出一些内存空间给同步队列缓存,只有在你设置的是不移除的情况下,才不用考率这个因素
- maxmemory-policy
- volatile-lru 使用lru算法移除key 支队设置了过期时间的key
- allkeys-lru 使用lru算法移除key
- volatile-random 在过期集合中移除随机的key 支队设置了过期时间的键
- allkeys-random 移除随机的key
- volatile-ttl 移除那些ttl值最小的key 即那些最近要过期的key
- noeviction 不进行移除,针对写操作,只是返回错误信息
- maxmemory-samoles
- 设置样本数量,lru算法和最小ttl算法并非是精确的算法,而是估算值,所以你可以设置样本的大小,redis默认会检查这么多个key并选择其中lru的那个
- maxclinets
- append only mode 追加
- appendonly
- appendfilename
- appendfsync
- always 同步持久化,每次发生数据变成会立即记录到磁盘,性能较差但数据完整性比较好
- everysec 出厂默认推荐 异步操作 每秒记录 如果一秒内宕机,有数据丢失
- no
- no-appendfsync-on-rewrite: 重写时是否可以运用appendfsync 用默认no即可,保证数据安全性。
- auto-aof-rewrite-min-size: 设置重写基准值
- auto-aof-rewrite-percentage: 设置重写的基准值
- 常见配置redis.conf介绍
- redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程; daemonize no
- 当redis以守护进程方式运行时,redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile执行; pidfile /var/run/redis.pid
- 指定redis监听端口 默认端口号是 6379; port 6379
- 绑定的主机地址; bind 127.0.0.1
- 当客户端闲置多长时间关闭链接,如果指定为0,标识关闭改功能; timeout 300
- 指定日志记录级别,redis支持4个级别:debug,verbose,notice,warning,默认verbose; loglevel verbose
- 日志记录方式,默认为标准输出,如果配置redis为守护进程的方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null; logfile stdout
- 设置数据库的数量,默认数据库为0,可以使用select <dbid> 命令在链接上指定数据库id; databases 16
- 指定在多场时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配置; save <seconds><changes> 默认3个条件 save 900 1 ; save 300 10; save 60 10000
- 指定储存至本地数据库时是否压缩数据,默认为yes,redis采用lzf压缩,如果为了节省cpu时间,可以关闭该选项,但会导致数据文件变动额巨大; rdbcompression yes
- 指定本地数据库文件名 默认值为dump.rdb; dbfilename dump.rdb
- 指定本地数据库存放目录; dir ./
- 设置当本机为slav服务时,设置master服务的ip地址及端口,在redis启动时,他会自动从master进行数据同步; slaveof <masterip> <masterport>
- 设置redis链接密码,如果配置了链接密码,客户端在链接redis时需要通过auth <password>命令提供密码,默认关闭; requirepass 123
- 当master服务设置了密码保护时,slav服务链接master的密码; masterauth <maseter-passwordr>
- 设置同一时间最大客户端连接数,默认限制,redis可以同时打开的客户端连接为redis进程可以打开的最大文件描述符数;0为不限制; maxclients128
- 指定redis最大内存限制,redis在启动时会把数据加载到内存中,达到最大内存后,redis会先尝试清除已到期或即将到期的key,当此方法处理后,仍然到达最大内存限制。将无法在进行写入操作但仍然可以读操作,redis新的vm机制,会把key存放内存,value会放在swap区; maxmemory <bytes>
- 指定是否在每次更新操作后进行日志记录,redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为redis本身通同步数据是按上面的save条件类同步的。所以有的数据会在一段时间内存在于内存中。默认no; appendonly no
- 指定更新日志文件名,默认为appendonly.aof; appendfilename appendpnly.aof
- 指定日志更新条件,共有3个选项; no:表示等操作系统进行数据缓存同步到磁盘(快);always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全);everysec:表示每秒同步; appendfsync everysec
- 指定是否使用虚拟内存机制,默认为no,简单的介绍一下,VM机制将数据分页存放,由redis将访问量较少的即冷数据swap到磁盘上,访问多的页面有磁盘自动缓存到内存中; vm-enabled no
- 虚拟内存文件路径,默认为 /tmp/redis.swap 不可多个redis实例共享 ; vm-swap-file /tmp/redis.swap
- 将所有大于vm-max-memony的数据存入虚拟内存,无论vm-max-memory设置多小所有索引数据都是内存存储的(redis的索引数据就是keys)也就是说当vm-max-memory设置为0的时候,其实就是所有value都存在于磁盘。默认值为0; vm-max-memory 0
- redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但是一个page上不能被多个对象共享,vm-page-size是要根据存储的数据带下来设定的。 vm-page-size 32
- 设置swap文件中的page数量,由于页表(一种表示页面空间或使用bitmap)是放在内存中的,在磁盘上每个8个pages将消耗1byte的内存; vm-pages 134217728
- 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长的时间延迟,默认为4; vm-max-threads 4
- 设置在向客户端应答时,是否把较小的包合并成为一个包发送,默认为开启; glueoutputbuf yes
- 指定在超过一定的数据或者最大的元素超过某一临界值时,采用一种特殊的哈希算法;hash-max-zipmap-entries 64 hash-max-zipmap-value 512
- 指定是否激活重置哈希,默认为开启; activerehashing yes
- 指定包含其他的配置文件,可以在同一主机上多个redis实例之间使用同一份配置文件,而通同时各个实例又拥有自己的特定配置文件; include /path/to/local.conf
四、redis持久化
- RDB(Redis DataBase)
- 解释
在指定的时间间隔内将内存的数据集快照写入磁盘,也就是行话将的sanpshot快照,它恢复时是将快照文件直接读到内存里;
redis会单独创建(fork)一个子进程来进行持久化,会先将数据写到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件整个过程中,主进程是不进行任何io操作的,这就确保了极高的性能,如果需要进行大规模数据恢复,且对于数据恢复的完整性不是非常敏感,那rdb方式比aof方式更加高效,rdb的缺点是最后一次持久化后的数据可能丢失
-
- rdb保存的是dump.rdb文件, 保存位置同上 snapshotting 参数
- 如何触发快照
配置文件中快照的配置
命令save或者bgsave; 1:save只管保存其他不管,全部堵塞;bgsave会在后台进行异步操作,快照同时还可以响应客户端请求,可以通过lastsave获取最后一次成功执行快照的时间
执行flushall 命令,也可能产生dump.rdb文件。但是是空文件
-
- 如何恢复
将备份文件(dump.rdb)移动到redis安装目录并启动服务
config get dir 获取目录
-
- 优势
适合大规模的数据恢复
对数据的完整性和一致性要求不高
-
- 劣势
在一定时间间隔做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改
fork的时候。内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
-
- 如何停止
动态所有停止 rdb保存规则的方法 redis-cli config set save ""
-
- 小结
rdb是一个非常紧凑的文件
rdb在保存rdb文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他的io操作,所以rdb持久化可以最大化redis的性能
与aof相比,rdb在恢复大的数据集的时候rdb的方式更快一些
数据丢失风险大
rdb需要经常fork子进程来保存数据集到磁盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致redis在一些毫秒级能不能响应客户端请求
- AOF
- 解释
以日志的形式记录每个操作,将redis执行的每个指令记录下来(读操作不记录),只需追加文件不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之redis重启的话就根据日志文件的内容将写指令从前到后执行一次,以完成数据的恢复工作
-
- aof保存的是appendonly.aof文件
- 配置位置
通过配置文件 appendonly , appendfilename 开始功能并设定文件
-
- aof启动/修复/恢复
- 正常恢复
- aof启动/修复/恢复
启动:设置yes; 修改配置文件开启aof功能
将有数据的aof文件复制一份保存到对应目录(config get dir)
恢复:重启redis然后重新加载
-
-
- 异常恢复
-
启动:设置yes; 修改配置文件开启aof功能
备份被写坏的aof文件
redis-check-aof --fix进行修复
重启redis然后重新加载
-
- rewrite
解释: aof采用文件追加方式,文件会越来越大,为避免出现这种情况,新增了重新机制。当aof文件的大小超过设定的阈值时,redis就会启动aof文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewrieaof
重写原理:aof文件持续增长而过大时,会fork出一条心进程,来将文件重写(也是先写临时文件最后在rename)遍历新进程中的数据,每条记录有一条的set语句,重写aof文件的操作并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照相似
触发机制:redis会记录上次重写时的aof大小,默认配置是当aof文件大小是上次rewrite后文件大小的一倍且文件大小大于64m触发
-
- 优势
每修改同步: appendfsync always 同步持久化,每次发生数据变更会立即记录到磁盘,性能较差但是数据完整性较好
每秒同步: appendfsync everysec 异步操作,每秒记录,如果一秒内宕机,有数据丢失
不同步: appendfsync no
-
- 劣势
相同数据集的数据而言aof文件远大于rdb文件,恢复速度慢于rdb
aof运行效率慢于rdb。每秒同步策略效率较好,不同效率和rdb相同
-
- 小结
aof文件是一个只进行追加的日志文件
redis可以在aof文件体积过大自动的在后台对aof文件进行重新
aof文件有序的保存了所有对数据执行的写操作,这些写操作以redis协议的格式保存,因此aof文件的内容非常容易被人读懂,对文件进行分析也很轻松。
对于相同的数据集来说,aof文件的体积通常大于rdb文件
根据fsync策略 aof的速度慢与rdb
- 总结
1、rdb持久化方式能够在指定的时间间隔能对你的数据进行快照存储
2、aof持久化方式记录每次对数据的写操作,当服务器重启的时候会重新这些命令来恢复原始的数据,aof命令以redis协议追加保存每次写操作到文件的末尾,redis还能对aof文件进行重写避免aof文件体积过大。
3、只做缓存,如果你只希望你的数据在服务器运行的时候存在也可以不使用任何持久化方式。
4、同时开启两种持久化方式:
1).这种情况下redis重启后优先载入aof文件来恢复原始数据,因为通常情况下aof文件比rdb文件保存的数据要完整。
2).rdb数据不实时同时使用两者是服务器也只会找aof文件。不建议只是用aof,因为rdb更适合用户备份数据库(aof不断变化不好备份),快速重启,而且不会有aof潜在的bug,留着作为万一的手段。
5、性能建议
1).因为rdb文件只用做后备用途,建议只在slave上持久化rdb文件,而且只要15分钟备份一次就可以保留 save 900 1
2).如果enable aof好吃实在最恶劣的情况下也只会丢失不超过两秒的数据,启动脚本比较简单只load自己的aof文件就可以了,代价一是带来了持续的io,二是aof rewrite过程中产生的心数据写到新文件造成的堵塞几乎是不可避免的只要硬盘许可,应该尽量减少aof rewrite的频率,aof重写的基础大小默认值64m太小了,可以设置5g以上,默认超过原来100%大小时重写可以改到适当的值
3).如果不enable aof,紧靠master-slave replication实现高可用行也可以,能减少一大笔io也减少rewrite带来的系统波动,代价是如果master/slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个master/slave中的rdb文件载入较新的那个
五、redis的事物
- 解释: 可以一次性指定多个命令,本质是一组命令的集合,一个事物中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞
- 用途: 一个队列中,一次性,顺序性,排他性的执行一系列命令
- 使用:
- 常用命令
- discard 取消事务,放弃执行事务块内的所有命令
- exec 执行所有事务块内的命令
- multi 标记一个事务块的开始
- unwatch 取消watch命令对所有key的监视
- watch key 监视一个或多个key,如果在事务执行之前这个key被其他命令所改动,那么事务将被打断
- 正常执行:
- 放弃事务
- watch监控:
- 悲观锁/乐观锁/CAS(check and set)
- 常用命令
悲观锁(pessimistic Lock):顾名思义,就是很悲观,每次拿数据的时候都认为别人会修改,所以每次在那数据时候都会上锁,这样别人想拿这个数据就会block知道他拿到锁,传统的关系型数据库就用到了很多这种锁机制,比如行锁,表锁,读锁,写锁等,都是在操作之前上锁。
乐观锁(Optiimistic Lock): 很乐观,每次去那数据的饿时候都任务别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制,乐观锁应用于多读的应用类型,这样可以提高吞吐量。 乐观锁策略,提交版本必须大于记录当前版本才能执行执行更新。
watch指令,类似乐观锁,事物提交时,如果key的值已被别的客户端改变,比如某个list已被别的客户端push/Pop过了,整个事务列队都不会被执行
通过watch命令在事务执行之前监控了多个keys,倘若在watch之后任何key的值发生了变化,exec命令执行的事务都将被放弃,同时返回nullmulti-bulk应答以通知调用者事务执行失败。
- 阶段
开启: 以multi开始一个事务
入队: 将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队里里面
执行: 有exec命令触发事务
- 特性
单独的隔离操作:事务中的所有命令都会序列化,按顺序地执行,事务在执行的过程中,不会被其他客户端发送过来的命令请求所打断。
没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交任何执行都不会被实际执行。也就不存在“事务内的查询要看到事务里的更新,在事务外查询不能看到” 这个让人万分头痛的问题
不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。
六、redis的发布订阅
- 解释: 进程间额一种消息通信模式:发送者pub发送消息,订阅者sub接受消息
- 命令:
- psubscribe 订阅一或多个符合给给定模式的频道
- pubsub 查看订阅与发布系统状态
- publist 将信息发送到指定的频道
- punsubscribe 退订所有给定模式的频道
- subscribe 定于给定的一个或多个频道的信息
- unsubscribe 指退订给定的频道
七、redis的复制(Master/Slave)
- 解释: 主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slave机制。master以写为主。 slave以读为主
- 作用: 读写分离; 容灾恢复;
- 使用
配置从库,不操作主库
从库配置: slaveof 主库ip 主库端口 ;
1. 客户端数据命令 SLAVEOF host port 连接 (每次与master断开之后需要重新间接)
2. 修改配置文件连接。
查看信息: info replication
上一个slave可以是狭义个slave的master slave同样可以接收其他slave的链接和同步请求,那么该slave作为了链条中下一个的master。可以减轻master的压力
中途变更转向,会清除之前的数据,重新建立拷贝最新的
反客为主: slaveof no one. 是当前数据库通知与其他数据的同步,转成主数据库
- 原理
slave启动成功链接到master后会发送一个sync(同步)命令
master借到命令启动后台的存盘进程,同时收集所有接收到的用户修改数据集命令,在后台进程执行完毕之后,master将传动整个数据文件到slave,以完成一次完全同步。
全量复制; 而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
增量复制:master继续讲新的所有收集到的修改命令一次传给slave,完成同步。
只要是重新连接master 一次完全同步(全量复制)将被自动执行
- 哨兵模式
反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转为主库
-
- 使用步骤
- 调整结构。6379 呆着80,81
- 在redis目录下新建sentinel.conf文件, 名字绝不能错
- 配置哨兵填写内容: sentinel monitor 被监控数据库名字(自定义) 127.0.0.1 6379 1 例: sentinel monitor host6379 127.0.0.1 6379 1
- 上面最后一个数字1 ,表示主机挂掉后slave投票看让谁接替成为主机,得票数多少后成为主机
- 启动哨兵: redis-sentinel sentinel.conf
- 一组sentinel能监控多个master
- 使用步骤
- 复制的缺点
由于所有的写操作都是现在master上操作,然后同步更新到slave上,所以从master同步到slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,slave机器数量的增加也会使这个问题更加严重。
八、redis的Java客户端Jedis
- jedisPool
import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class JedisUtil { private static volatile JedisPool jedisPool = null; //被volatile修饰的变量不会被本地线程缓存,对该变量的读写都是直接操作共享内存。 private JedisUtil() { } public static JedisPool getJedisPoolInstance() { if (null == jedisPool) { synchronized (JedisUtil.class) { if (null == jedisPool) { JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxActive(1000); poolConfig.setMaxIdle(32); poolConfig.setMaxWait(100 * 1000); poolConfig.setTestOnBorrow(true); jedisPool = new JedisPool(poolConfig, "127.0.0.1"); } } } return jedisPool; } public static void release(JedisPool jedisPool, Jedis jedis) { if (null != jedis) { jedisPool.returnResourceObject(jedis); } } }
- 配置
maxActive | 控制一个pool可分配多少个jedis实例,通过pool.getResource来获取,如果赋值为-1,则表示不限制,如果pool已经分配了maxActive个jedis实例,则此状态为exhausted |
maxIdle | 控制一个pool最多有多少个状态为idle (空闲) 的jedis实例 |
whenEXhaustedActive | 表示当pool中的jedis实例都被allocated完时,pool要采取的操作默认有三种 |
1. WHEN_EXHAUSTED_FAIL | 表示无jedis实例时,直接抛出NoSuchElementException |
2. WHEN_EXHAUSTED_BLOCK | 表示堵塞,或者达到maxWait直接抛出JedisConnectionException |
3. WHEN_EXHAUSTED_GROW | 则表示新建一个jedis实例,也就是说设置的maxActive无用 |
maxWait | 当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛JedisConnectionException |
testOnborrow | 获得一个jedis实例的时候是否检查可连接性,如果为true则得到的jedis实例均是可用的 |
testOnReturn | return一个jedis实例给pool,是否检查连接可用性 ping() |
testWhileldle | 如果为true,表示有一个idle object evitor线程对idle object进行扫描,如果validata失败,次object会被从pool中drop掉,这一项只有在timeBetweenEvictionRunMillis大于0时才有意义 |
timeBetwwenEvictionRunsMillis | 表示idle object evitor两次扫描之间要sleep的毫秒数 |
numTestsPerEvictionRun | 表示idle object evitor 每次扫描的最多的对象数 |
minEvictableIdleTimeMillis | 表示已个对象至少停留在ile状态的最短时间,然后才能被idle object evitor扫描并驱逐,这一项只有在timeBetweenEvictionRunMillis大于0时才有意义 |
softMinEvictableIdleTimeMillis | 在minEvictableIdleTimeMillis基础上,加入了至少minIdle个对象已经在pool里面了,如果为-1,evicted不会根据idle time驱逐任何对象,如果minEvictableIdleTimeMillis >0,则此项设置无意义,且只有在timeBetweenEvictionRunMillis大于0时才有意义 |
lifo | borrowObject 返回对象时,是采用DEFAULT_INFO 如果为False 则表示FIFO队列 |
jedisPoolConfig 对一些参数的默认设置如下:
testWhiileIdle = true
minEvictableIdleTimeMillis=60000
timeBetweenEvictionRunsMillis=30000
numTestsPerEvictionRun=1