天天看点

Redis详解(二)

一、redis认证

二、redis事务

三、Connection&server相关命令

四、Redis的发布与订阅//充当mq的功能

五、Redis持久化

六、redis复制

七、master-slave实现

八、sentinal哨兵

九、redis限制

十、redis性能测试

redis认证:

    vim /etc/redis.conf 

        requirepass redispass //密码

    [root@node1 ~]# systemctl restart redis

    [root@node1 ~]# redis-cli -h 192.168.4.106

    192.168.4.106:6379> select 0

    (error) NOAUTH Authentication required.

    192.168.4.106:6379> auth redispass

    OK

    OK    

清空数据库

    flushdb:清空当前库

    flushall:清空所有库

1.MULTI用来组装一个事务;

2.EXEC用来执行一个事务;

3.DISCARD用来取消一个事务;

4.WATCH用来监视一些key,一旦这些key在事务执行之前被改变,则取消事务的执行。

我们来看一个MULTI和EXEC的例子:

RDBMS的事务:一组相关操作,是原子性的:满足ACID :原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

redis的事务:可以将多个命令绑定在一起,顺序执行。通过multi,exec,watch等命令实现事务功能;

    在事务执行过程中,redis不会中断当前事务去执行其他client的指令。

127.0.0.1:6379> multi

OK

127.0.0.1:6379> set ip 192.168.0.1

QUEUED

127.0.0.1:6379> set port 800 //放到队列中

127.0.0.1:6379> exec //一起执行

1) OK

2) OK

watch:在事务执行过程中,施加乐观锁 //不支持回滚

    在exec之前,监视 指定的数据key是否在 multi和exec之间发生修改操作,有变动则不予执行事务

    事务中关联的 键 的监视操作。    

    //乐观锁,只是看他是否被修该,一旦被修改了,就不予执行。在事务过程中仍然可以被修改

redis不支持回滚操作,这是和mysql事务最大的区别

    事务有10个操作,第5个命令错误。redis事务会忽略第5个错误,执行到最后。

    redis目标:简单、高效

    redis的原子性:事务队列中的任务,要么全部执行,要么全都不执行

    redis的一致性:在检查入队时的一致性,例如输入为错误命令 //语法级别

    redis的隔离性:单线程,在执行事务中,不会执行其他操作,但是可以接受用户请求到queue中

    redis的持久性:依赖于server是否启用持久化功能 

        rdb或者aof //快照和追加到文件    

示例:乐观锁

<code>终端1:            </code>

<code>    </code><code>127.0.0.1:6379&gt; </code><code>watch</code> <code>ip </code>

<code>    </code><code>OK</code>

<code>    </code><code>127.0.0.1:6379&gt; multi</code>

<code>    </code><code>127.0.0.1:6379&gt; </code><code>set</code> <code>ip 10.0.0.1</code>

<code>    </code><code>QUEUED</code>

<code>    </code><code>127.0.0.1:6379&gt; get ip</code>

<code>终端2:</code>

<code>    </code><code>127.0.0.1:6379&gt; </code><code>set</code> <code>ip 172.16.100.1</code>

<code>    </code><code>"172.16.100.1"</code>

<code>终端1:        </code>

<code>    </code><code>127.0.0.1:6379&gt; </code><code>exec</code>

<code>    </code><code>(nil)  </code><code>//</code><code>事务执行失败</code>

<code>    </code> 

<code>redis的一致性************        </code>

<code>127.0.0.1:6379&gt; multi</code>

<code>OK</code>

<code>127.0.0.1:6379&gt; </code><code>set</code> <code>jsidfjd</code>

<code>(error) ERR wrong number of arguments </code><code>for</code> <code>'set'</code> <code>command</code>

<code>127.0.0.1:6379&gt; </code><code>exec</code>

<code>(error) EXECABORT Transaction discarded because of previous errors.</code>

<code>redis的原子性************</code>

<code>127.0.0.1:6379&gt; </code><code>set</code> <code>ip 10.0.0.1</code>

<code>QUEUED</code>

<code>127.0.0.1:6379&gt; </code><code>set</code> <code>aa</code>

<code>127.0.0.1:6379&gt; </code><code>exec</code>    <code>//</code><code>因为有语法错误,因此都没有执行</code>

help @connections

<code>    </code><code>auth:</code>

<code>    </code><code>ping</code><code>: 验证服务器是否在线</code>

<code>    </code><code>echo</code> <code>“hello redis"</code>

<code>    </code><code>quit:</code>

<code>    </code><code>select</code><code>:选择指定的DB</code>

help @server 

<code>    </code><code>bgsave:异步存储数据到disk</code>

<code>    </code><code>client setname: 为连接设置名字 </code><code>//</code><code>只能为自己修改名字</code>

<code>    </code><code>client getname :获取当前客户端的链接名</code>

<code>    </code><code>client </code><code>kill</code> <code>ip:port </code><code>//kill</code> <code>client的一个连接</code>

<code>    </code><code>client list :查看链接</code>

<code>    </code><code>config get  </code><code>//redis</code><code>的多数配置都可以在运行时修改</code>

<code>    </code><code>config </code><code>set</code> <code>//</code><code>配置</code><code>file</code><code>中的参数 ,可以在内存中修改</code>

<code>    </code><code>config rewrite </code><code>//</code><code>在内存中修改的操作,写入到配置文件</code>

<code>    </code><code>info </code><code>//</code><code>服务器的所有统计数据</code>

<code>    </code><code>info Memory </code><code>//</code><code>指定只看内存信息</code>

<code>    </code><code>info Cluster </code><code>//</code><code>获取指定section的内容</code>

<code>    </code><code>config resetstat </code><code>//</code><code>重置info的所有数据</code>

<code>    </code><code>dbsize:    限制所有的键的数量</code>

<code>    </code><code>bgsave: </code><code>//</code>

<code>    </code><code>save:</code>

<code>    </code><code>lastsave:获取最近一次成功保存到disk的 timestamp</code>

<code>    </code><code>monitor:实时监控接受到的请求</code>

<code>    </code><code>shutdown</code> <code>[nosave</code><code>/save</code> <code>]:同步所有数据到disk后,关闭</code>

<code>    </code><code>slaveof :配置主从</code>

<code>    </code><code>slowlog:管理慢查询日志</code>

<code>    </code><code>sync</code><code>:复制功能的内建命令 </code><code>//</code><code>同步master</code>

<code>    </code><code>time</code><code>:获取当前server时间</code>

发布与订阅:发布者在订阅者订阅之前的发布数据默认是收取不到的

redis的发布与订阅功能:(publish/subscribe)

    生产者把信息发布在指定频道上,订阅者从指定的频道去订阅自己关注的信息即可

    SUBSCRIBE:订阅一个或多个 队列/频道 

    unsubscribe 退订此前订阅的频道

    psubscribe "new.i[to]" //订阅2个频道

        psubscribe "new.*" //也可以

示例:发布与订阅

<code>终端1:</code>

<code>    </code><code>127.0.0.1:6379&gt; SUBSCRIBE news  </code><code>//</code><code>可以同时订阅多个channel</code>

<code>    </code><code>Reading messages... (press Ctrl-C to quit)</code>

<code>    </code><code>1) </code><code>"subscribe"</code>

<code>    </code><code>2) </code><code>"news"</code>

<code>    </code><code>3) (integer) 1</code>

<code>    </code><code>127.0.0.1:6379&gt; PUBLISH news hello</code>

<code>    </code><code>(integer) 1</code>

<code>    </code><code>1) </code><code>"message"</code>

<code>    </code><code>2) </code><code>"news"</code>  <code>//</code><code>频道名</code>

<code>    </code><code>3) </code><code>"hello"</code>     <code>//</code><code>内容</code>

五、Redis持久化    

redis如何实现持久化

    redis默认工作在内存中

持久化

    SAVE:将数据同步保存到磁盘;

    BGSAVE:将数据异步保存到磁盘;

    LASTSAVE:返回上次成功将数据保存到磁盘的 UNIX 时戳;

    SHUNDOWN:将数据同步保存到磁盘,然后关闭服务。

持久化:RDB和AOF

RDB:snapshot,二进制格式,默认机制

    按事先定制的策略,周期性的将数据保存到disk中;数据文件默认为dump.rdb

    客户端也可使用save或bgsave密令启动快照保存机制。

        save:异步方式实现,在主线程中保存快照:在save过程中,其他所有client请求都是block的

            完整写入内存数据到disk,而不是增量的同步

        bgsave:异步background save,不会阻塞client请求,使用一个新的进程

AOF:append only file,把每个 写命令 追加到文件尾部。

    假如incr命令,执行100次,默认需要记录100次

    附加日志类型的持久化存储:问题:文件会变的越来越大,

    但是redis能够合并aof的持久化文件,bgrewriteaof 命令来实现。

    例如 set count=100,直接修改aof文件,用来节约空间

127.0.0.1:6379&gt; dir //获取备份目录

==============================================================================    

    记录每一次写操作至指定的文件尾部实现持久化,当redis重启时,可重新执行文件中的命令在内存中重建数据库

        BGREWRITEAOF:aof文件重写,

    不会读取正在使用的AOF文件,而通过将内存中的数据以命令的方式保存到临时文件中,完成后替换原有的AOF文件来实现。

Redis在实现RDB模式时的实现方式:

    redis调用fork创建一个子进程,父进程继续处理client的请求,子进程负责将内存中的内容快照 到disk 中。

    linux有COW(copy on write)机制,子进程和父进程会共享相同的物理页面,

    当父进程要写请求时,os会为父进程创建一个副本,因此子进程所实现的保存,一定是时间点一致的数据。内核的特性。

        当子进程快照写入完成后,os会用副本覆盖源文件。然后子进程退出

    不足:一定会有一部分数据丢失,rdb保存的时间点之后的时间点会丢失

    RDB:

        SAVE 900 1 

        SAVE 300 10

        SAVE 60 10000 //周期性的工作机制。

        SAVE "" //关闭RDB功能

        stop-writes-on-bgsave-error yes //在持久化时

        rdbcompression yes //压缩rdb文件

        rdbchecksum yes//对rdb的镜像文件进行校验

        dbfilename dump.rdb 

        dir /var/lib/redis 

            //redis-cli&gt; config get dir //可以获取配置

redis在实现AOF模式时的实现方式

    每一个命令发出后,直接追加到append到文件中 

    重建过程:redis父进程调用fork,启动一个子进程,子进程根据内存中现有的文件的数据,在临时文件中,写入一个数据库重建的命令。

        父进程继续处理client请求,client新的请求除了把命令写入到文件中,还要把新的命令缓存起来,放到缓存队列中,后续执行。

    当子进程把快照内容写入到新的AOF文件后,通知父进程,父进程会用新的AOF替换老的AOF文件,并把这个操作启动之后,新收到的请求命令,追加到新的AOF文件中

    默认每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中)

    1.redis主进程fork一个子进程

    2.子进程根据redis内存中的数据创建数据库重建命令序列于临时文件中

    3.父进程继续接受客户端请求,并且会把这些请求中的写操作继续追加到原来的AOF文件;额外地,这些新的写请求还会被放置于一个缓冲队列中

    4.子进程重写完成后通知父进程,父进程把缓冲中的命令写到临时文件中

    5.父进程用临时文件替换老的aof文件

AOF方式的另一个好处,我们通过一个“场景再现”来说明。某同学在操作redis时,不小心执行了FLUSHALL,导致redis内存中的数据全部被清空了,这是很悲剧的事情。不过这也不是世界末日,只要redis配置了AOF持久化方式,且AOF文件还没有被重写(rewrite),我们就可以用最快的速度暂停redis并编辑AOF文件,将最后一行的FLUSHALL命令删除,然后重启redis,就可以恢复redis的所有数据到FLUSHALL之前的状态了。是不是很神奇,这就是AOF持久化方式的好处之一。但是如果AOF文件已经被重写了,那就无法通过这种方法来恢复数据了。    

但AOF方式也同样存在缺陷,比如在同样数据规模的情况下,AOF文件要比RDB文件的体积大。而且,AOF方式的恢复速度也要慢于RDB方式。

如果在追加日志时,恰好遇到磁盘空间满、inode满或断电等情况导致日志写入不完整,也没有关系,redis提供了redis-check-aof工具,可以用来进行日志修复。    

    appendonly no //默认是关闭的

    appendfilename "appendonly.aof" //追加到哪个文件

    # appendfsync always //每次收到写请求,就执行操作

    appendfsync everysec //每s一次

    # appendfsync no //append的功能自行不会触发写操作,所有写操作都是提交给OS,由OS自行决定如何写。

            //由内核决定如何进行写操作

    no-appendfsync-on-rewrite no //yes:表示,对重写操作,对新写入的操作,不做fsync,而是暂存到队列中

    auto-aof-rewrite-percentage 100 //本次重新的aof文件是上次重新文件的2倍时,执行重写。

        (当前写入日志文件的大小超过上一次rewrite之后的文件大小的百分之100时就是2倍时触发Rewrite)

    auto-aof-rewrite-min-size 64mb //刚开始的时候,1个1s后,4个大于1的2倍,会发起重写操作,显然不合理,要设置最小aof文件大小

    aof-load-truncated yes        //

可以同时启动RDB和AOF,

注意:持久本身不能取代备份,还应该指定备份策略,对redis数据库及逆行定期备份

假如同时启用AOF和RDB    

    两个同时满足,需要重写

        bgsave和rewrite不会同时执行,redis只会让一个执行,为了避免过大的磁盘IO,逐个执行

RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;

AOF,则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。

其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。

如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache一样。

特点:    

    一个master可以有多个slave,一个slave也可以有自己的slave

    支持链式复制功能:

    master以非阻塞方式同步数据至slave//master会继续接受一个或多个slave的同步请求

<code>slaveof &lt;masterip&gt; &lt;masterport&gt;</code>

<code>masterauth &lt;master-password&gt;  </code><code>//</code><code>主redis设置了验证密码的话(使用requirepass来设置)</code>

<code>slave-</code><code>read</code><code>-only </code><code>yes</code>

<code>repl-</code><code>ping</code><code>-slave-period 10  </code><code>//slave</code><code>默认每10s向master发送</code><code>ping</code><code>包</code>

<code>repl-timeout 60  </code><code>//</code><code>设置</code><code>ping</code><code>超时时间,确保这个时限比repl-</code><code>ping</code><code>-slave-period的值要大,否则每次主redis都会认为从redis超时。</code>

<code>repl-disable-tcp-nodelay no  </code><code>//</code><code>主从同步时是否禁用TCP_NODELAY。开启:主redis会使用更少的TCP包和更少的带宽来向从redis传输数据。但是这可能会增加一些同步的延迟,大概会达到40毫秒左右。如果你关闭了TCP_NODELAY,那么数据同步的延迟时间会降低,但是会消耗更多的带宽</code>

<code>repl-backlog-size 1mb </code><code>//</code><code>同步队列长度。队列长度(backlog)是主redis中的一个缓冲区,在与从redis断开连接期间,主redis会用这个缓冲区来缓存应该发给从redis的数据。这样的话,当从redis重新连接上之后,就不必重新全量同步数据,只需要同步这部分增量数据即可。</code>

<code>repl-backlog-ttl 3600 </code><code>//</code><code>如果主redis等了一段时间之后,还是无法连接到从redis,那么缓冲队列中的数据将被清理掉。我们可以设置主redis要等待的时间长度。如果设置为0,则表示永远不清理。默认是1个小时。</code>

<code>slave-priority 100 </code><code>//redis</code><code>优先级,在主redis持续工作不正常的情况,优先级高的从redis将会升级为主redis。而编号越小,优先级越高。比如一个主redis有三个从redis,优先级编号分别为10、100、25,那么编号为10的从redis将会被首先选中升级为主redis。当优先级被设置为0时,这个从redis将永远也不会被选中。默认的优先级为100。</code>

<code>min-slaves-to-write 3 </code><code>//redis</code><code>提供了可以让master停止写入的方式,如果配置了min-slaves-to-write,健康的slave的个数小于N,mater就禁止写入。master最少得有多少个健康的slave存活才能执行写命令。这个配置虽然不能保证N个slave都一定能接收到master的写操作,但是能避免没有足够健康的slave的时候,master不能写入来避免数据丢失。设置为0是关闭该功能。</code>

<code>min-slaves-max-lag 10 </code><code>//</code><code>#延迟小于min-slaves-max-lag秒的slave才认为是健康的slave。</code>

<code>slave-serve-stale-data </code><code>yes</code>    <code>//</code><code>联系不到master之后,仍然使用过期数据</code>

<code>repl-diskless-</code><code>sync</code> <code>no </code><code>//</code><code>当硬盘太慢的时候,启用该值 </code>

<code>repl-diskless-</code><code>sync</code><code>-delay 5 </code><code>//</code><code>延迟操作时间</code>

当从redis失去了与主redis的连接,或者主从同步正在进行中时,redis该如何处理外部发来的访问请求呢?这里,从redis可以有两种选择:

    第一种选择:如果slave-serve-stale-data设置为yes(默认),则从redis仍会继续响应客户端的读写请求。

    第二种选择:如果slave-serve-stale-data设置为no,则从redis会对客户端的请求返回“SYNC with master in progress”,当然也有例外,当客户端发来INFO请求和SLAVEOF请求,从redis还是会进行处理。

    你可以控制一个从redis是否可以接受写请求。将数据直接写入从redis,一般只适用于那些生命周期非常短的数据,因为在主从同步时,这些临时数据就会被清理掉。自从redis2.6版本之后,默认从redis为只读。

只读的从redis并不适合直接暴露给不可信的客户端。为了尽量降低风险,可以使用rename-command指令来将一些可能有破坏力的命令重命名,避免外部直接调用。比如:

rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

主从情况下的timeout:

1.以从redis的角度来看,当有大规模IO传输时。

2.以从redis的角度来看,当数据传输或PING时,主redis超时

3.以主redis的角度来看,在回复从redis的PING时,从redis超时    

MONITOR:实时转储收到的请求; //master和slave之间进行的ping-pong也可以看到

    192.168.4.106 server

    192.168.4.109 slave

server: 

    bind 0.0.0.0 

    service redis resart //没有认证密码

slave:    

    service redis resart     

<code>[root@node2 ~]</code><code># redis-cli -h 192.168.4.109</code>

<code>192.168.4.109:6379&gt; SLAVEOF 192.168.4.106 6379</code>

<code>OK Already connected to specified master</code>

<code>192.168.4.109:6379&gt; get ip</code>

<code>"172.16.100.1"</code>

<code>192.168.4.109:6379&gt; config get slaveof</code>

<code>1) </code><code>"slaveof"</code>

<code>2) </code><code>"192.168.4.106 6379"</code>    

<code>192.168.4.109:6379&gt; key * </code><code>//</code><code>查看所有的key</code>

<code>192.168.4.109:6379&gt; config </code><code>set</code> <code>masterauth </code><code>"redispass"</code> <code>//slave</code><code>通过auth进行认证</code>

<code>    </code><code>注意:可以在同一个主机上启动多个redis,使用不同的端口接口</code>

<code>    </code><code>如果主redis设置了验证密码的话(使用requirepass来设置),则在从redis的配置中要使用masterauth来设置校验密码,否则的话,主redis会拒绝从redis的访问请求。</code>

<code>192.168.4.106:6379&gt; info Replication</code>

<code># Replication</code>

<code>role:master</code>

<code>connected_slaves:1</code>

<code>slave0:ip=192.168.4.109,port=6379,state=online,offset=575,lag=1</code>

<code>master_repl_offset:589</code>

<code>repl_backlog_active:1</code>

<code>repl_backlog_size:1048576</code>

<code>repl_backlog_first_byte_offset:2</code>

<code>repl_backlog_histlen:588</code>

<code>//</code><code>默认slaveof 之后,slave将变成只读</code>

主从架构问题:主故障,从不会执行写操作

redis引入了sentinel哨兵机制。监控整个主从架构。

    [监控主机] //sentinel会在主node挂的时候,选取一个从作为主node

[master]    

-----------------------

[s1]    [s2]    [s3]

前端代理会向sentinal发起查询请求,获取新的master node

万一sentinal故障:或者sentinal联系不到master,因此sentinal可以做集群,例如3个sentinal节点,避免误判

sentinal只监控主的,从master获取从的配置信息,一旦主故障,则选一个从为主

sentinal:

    用于管理多个redis服务器实现HA

        监控

        通知

        自动故障转移

        流言协议[sentinal之间接受master是否下线的消息],投票协议[决定是否执行故障迁移,以及选取哪一个为主master]

redis-server --sentinal 在启动的时候,指定sentinal可以自己成为sentinal 服务器

    redis-sentinal /path/to/file.conf  //专用命令,配置文件

sentinal启动:

    1.sentinal初始化自身服务器,运行redis-server中专用于sentinal功能的代码

    2.初始化sentinal状态,根据给定的配置文件,初始化监控的master服务器列表

    3.创建连向master的连接

专用配置文件:

/etc/redis-sentinal.conf 专用配置文件

port 26379     

(1)sentinel monitor mymaster 127.0.0.1 6379 2 //监控的主节点

    mymaster是自己取名,master-name,可以不是主机名,随意

    2:quorum 法定票数,至少2票,才可以启动集群

    //该条目可以出现多个

(2)sentinel down-after-milliseconds mymaster 30000

    master多少时间联系不到后为 down 离线

(3)sentinel parallel-syncs mymaster 1

    刚设定为新master时,允许同时多少个slave发起同步请求

(4)sentinel failover-timeout mymaster 18000

    故障转移的超时时间。在3min内不能把该slave提升为master,则故障转移失败

(5)logfile /var/log/redis/sentinel.log    

setinal只需要知道master节点,从node,sentinal会从主node获取的

主观下线:一个sentinal发现master找不到了,认为其down了

客观下线: 所有sentinal都认为该master down,

    sentinal会每隔1s 探测 ping(pong)

常用命令:

    sentinal masters

    sentinal slaves master_name

    sentinal get-master-addr-by-namne master_name

    sentinal reset //清除所有状态

    sentinal failover master_name //强制故障转移

实现:

    启动三个redis

    1主,2从,1个sentinal,让主的下线然后查看效果 //取消认证功能

[root@node1 lib]# mkdir /etc/redis

[root@node1 lib]# cp /etc/redis.conf /etc/redis

[root@node1 lib]# cd /etc/redis

[root@node1 redis]# cp redis.conf redis.conf.2

[root@node1 redis]# cp redis.conf redis.conf.3

[root@node1 redis]# mkdir -pv /redis/{db1,db2,db3}

[root@node1 redis]# chown -R redis.redis /redis/

<code>(1)默认</code>

<code>    </code><code>vim redis.conf </code>

<code>bind 0.0.0.0</code>

<code>port 6379</code>

<code>logfile </code><code>/var/log/redis/redis</code><code>.log</code>

<code>pidfile </code><code>/var/run/redis/redis</code><code>.pid</code>

<code>daemonize </code><code>yes</code> <code>//</code><code>能够在后台运行</code>

<code>protected-mode no</code>

<code>(2)vim redis.conf.2</code>

<code>port 6380</code>

<code>pidfile </code><code>/var/run/redis/redis2</code><code>.pid</code>

<code>logfile </code><code>/var/log/redis/redis2</code><code>.log    </code>

<code>dir</code> <code>/redis/db2</code>

<code>daemonize </code><code>yes</code>

<code>(3)    vim redis.conf.3</code>

<code>port 6381</code>

<code>pidfile </code><code>/var/run/redis/redis3</code><code>.pid</code>

<code>logfile </code><code>/var/log/redis/redis3</code><code>.log    </code>

<code>dir</code> <code>/redis/db3</code>

<code>[root@node1 redis]</code><code># redis-server /etc/redis/redis.conf</code>

<code>[root@node1 redis]</code><code># redis-server /etc/redis/redis.conf.2</code>

<code>[root@node1 redis]</code><code># redis-server /etc/redis/redis.conf.3    </code>

<code>[root@node1 redis]</code><code># ss -tunl |grep -E "6379|6380|6381"</code>

<code>tcp    LISTEN     0      128       *:6379                  *:*                  </code>

<code>tcp    LISTEN     0      128       *:6380                  *:*                  </code>

<code>tcp    LISTEN     0      128       *:6381                  *:*       </code>

<code>6379为主,其他都是从</code>

三个终端:

1.6379

[root@node2 ~]# redis-cli -h 192.168.4.106 -p 6379

192.168.4.106:6379&gt; config set requirepass masterpass

192.168.4.106:6379&gt; config set masterauth mastermaster

//在mater上set 添加新值,slave会立即看到

2.6380

[root@node2 ~]# redis-cli -h 192.168.4.106 -p 6380

192.168.4.106:6380&gt; slaveof 192.168.4.106 6379

192.168.4.106:6380&gt; config set masterauth masterpas //和master的requirepass一致

192.168.4.106:6380&gt; keys *

1) "port"

2) "ip"

3) "mm"

4) "kk"

5) "nn"

3.6381

[root@node2 ~]# redis-cli -h 192.168.4.106 -p 6381

192.168.4.106:6381&gt; slaveof 192.168.4.106 6379

192.168.4.106:6381&gt; config set masterauth masterpass

192.168.4.106:6381&gt; info Replication    

192.168.4.106:6380&gt; keys *    

启动sentinal配置,只启动一个sentinal

192.168.4.109:

[root@node2 ~]# cp /etc/redis-sentinel.conf /etc/redis/

[root@node2 ~]# cd /etc/redis/

[root@node2 redis]# vim redis-sentinel.conf

1.port :当前Sentinel服务运行的端口

2.dir : Sentinel服务运行时使用的临时文件夹

3.sentinel monitor master001 192.168.110.101 6379 2:Sentinel去监视一个名为master001的主redis实例,这个主实例的IP地址为本机地址192.168.110.101,端口号为6379,而将这个主实例判断为失效至少需要2个 Sentinel进程的同意,只要同意Sentinel的数量不达标,自动failover就不会执行

4.sentinel down-after-milliseconds master001 30000:指定了Sentinel认为Redis实例已经失效所需的毫秒数。当实例超过该时间没有返回PING,或者直接返回错误,那么Sentinel将这个实例标记为主观下线。只有一个 Sentinel进程将实例标记为主观下线并不一定会引起实例的自动故障迁移:只有在足够数量的Sentinel都将一个实例标记为主观下线之后,实例才会被标记为客观下线,这时自动故障迁移才会执行

5.sentinel parallel-syncs master001 1:指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长

6.sentinel failover-timeout master001 180000:如果在该时间(ms)内未能完成failover操作,则认为该failover失败

7.sentinel notification-script &lt;master-name&gt; &lt;script-path&gt;:指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,但是很常用     

[root@node2 redis]# egrep -v "^#|^$" redis-sentinel.conf 

sentinel monitor mymaster 192.168.4.106 6380 1 //有1个哨兵认为其故障,就确定故障

sentinel down-after-milliseconds mymaster 3000

sentinel failover-timeout mymaster 18000

sentinel auth-pass mymaster redispass

logfile "/var/log/redis/sentinel.log"

protected-mode no

daemonize yes     

sentinel auth-pass mymaster redispass //密码,没有密码,因此没有使用

# Generated by CONFIG REWRITE

sentinel known-slave mymaster 192.168.2.103 6380

sentinel known-slave mymaster 192.168.2.103 6381  //生成的

[root@node2 redis]# redis-sentinel /etc/redis/redis-sentinel.conf    

[root@node2 ~]# redis-cli -h 192.168.4.109 -p 26379    

sentinel masters //查看master所在的node

sentinel slaves mymaster //查看从s

kill 主node进程 6379

info //查看新的master 变为 6380

sentinel master //可以看到

在 6381上

    info replication //查看master

重新启动master //6379

26379:info 端口仍然为6380

    sentinel slaves mymaster //原主依然为从

maxclients 10000 //如果达到了此限制,redis会拒绝新请求,并发出“max number of clients reached”回应。

maxmemory &lt;bytes&gt; //一旦到达内存使用上限,redis将会试图移除内部数据,移除规则可以通过maxmemory-policy来指定。

    如果你的redis是主redis(说明你的redis有从redis),那么在设置内存使用上限时,需要在系统中留出一些内存空间给同步队列缓存,只有在你设置的是“不移除”的情况下,才不用考虑这个因素。

对于内存移除规则来说,redis提供了多达6种的移除规则。他们是:

1.volatile-lru:使用LRU算法移除过期集合中的key

2.allkeys-lru:使用LRU算法移除key

3.volatile-random:在过期集合中移除随机的key

4.allkeys-random:移除随机的key

5.volatile-ttl:移除那些TTL值最小的key,即那些最近才过期的key。

6.noeviction:不进行移除。针对写操作,只是返回错误信息。

无论使用上述哪一种移除规则,如果没有合适的key可以移除的话,redis都会针对写请求返回错误信息。

LRU算法和最小TTL算法都并非是精确的算法,而是估算值。所以你可以设置样本的大小。假如redis默认会检查三个key并选择其中LRU的那个,那么你可以改变这个key样本的数量。

maxmemory-samples 3

<code>info memory: </code><code>//</code><code>实际占用内存</code>

<code>    </code><code>used_memory:13490096 </code><code>//</code><code>数据占用了多少内存(字节)</code>

<code>    </code><code>used_memory_human:12.87M </code><code>//</code><code>数据占用了多少内存(带单位的,可读性好)</code>

<code>    </code><code>used_memory_rss:13490096  </code><code>//redis</code><code>占用了多少内存,常驻内存集</code>

<code>    </code><code>used_memory_peak:15301192 </code><code>//</code><code>占用内存的峰值(字节)</code>

<code>    </code><code>used_memory_peak_human:14.59M </code><code>//</code><code>占用内存的峰值(带单位的,可读性好)</code>

<code>    </code><code>used_memory_lua:31744  </code><code>//lua</code><code>引擎所占用的内存大小(字节)</code>

<code>    </code><code>mem_fragmentation_ratio:1.00  </code><code>//</code><code>内存碎片率</code>

<code>    </code><code>mem_allocator:libc </code><code>//redis</code><code>内存分配器版本,在编译时指定的。有libc、jemalloc、tcmalloc这3种。</code>

redis-benchmark [option] [option value]

$ redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000

100个并发连接,100000个请求,检测host为localhost 端口为6379的redis服务器性能

<code>-h      指定服务器主机名        127.0.0.1</code>

<code>-p      指定服务器端口  6379</code>

<code>-s      指定服务器 socket</code>

<code>-c      指定并发连接数  50</code>

<code>-n      指定请求数      10000</code>

<code>-d      以字节的形式指定 SET</code><code>/GET</code> <code>值的数据大小   2</code>

<code>-k      1=keep alive 0=reconnect        1</code>

<code>-r      SET</code><code>/GET/INCR</code> <code>使用随机 key, SADD 使用随机值</code>

<code>-P      通过管道传输 &lt;numreq&gt; 请求      1</code>

<code>-q      强制退出 redis。仅显示 query</code><code>/sec</code> <code>值</code>

<code>--csv   以 CSV 格式输出</code>

<code>-l      生成循环,永久执行测试</code>

<code>-t      仅运行以逗号分隔的测试命令列表。</code>

<code>-I      Idle 模式。仅打开 N 个 idle 连接并等待。</code>

参考:

https://piaosanlang.gitbooks.io/redis/content/happy/section2.html

https://www.cnblogs.com/wyy123/p/6078593.html

https://yq.aliyun.com/articles/226052    

http://www.cnblogs.com/hjfeng1988/p/6144352.html

http://chong-zh.iteye.com/blog/2175166

本文转自MT_IT51CTO博客,原文链接:http://blog.51cto.com/hmtk520/2056357,如需转载请自行联系原作者