码迷,mamicode.com
首页 > 其他好文 > 详细

Redis 在CentOS 6上的 安装和部署以及redis的主从复制sentinel实现HA

时间:2018-06-21 11:52:02      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:red   时间   比较   mon   操作   失败   处理   love   star   

一、简介
Redis是基于内存的存储,所有数据都工作与内存中,基于键值存储(key-value store),经常拿来跟memcached做比较;memcached没有持久能力,Redis有持久能力,可以把内存中的数据写入到磁盘中;memcached是多线程服务器,redis是单线程服务器,一个线程响应所有的客户端请求。

Redis的数据的持久可以有两种机制来实现:一是基于RDB,另一种机制是基于AOF来实现。

从本质上来讲Redis是一个高级的key-value store 和数据结构存储,Redis出了能存储键值这种简单的格式的数据,还能存储列表、集合、字典、hash等数据类型的数据。

Redis 也支持主从,默认有一个工具sentinel来实现redis的主从架构,并实现主服务器的高可用。

官方网站:https://redis.io/

二、试验环境

CentOS 6.6

IP:
node1: 10.0.0.6
node2: 10.0.0.7
node3: 10.0.0.8

二、安装部署

可以源码安装(官方下载),也可以yum安装(需要epel源),我这里yum安装。

[root@linux-node1 ~]# yum install redis
[root@linux-node1 ~]# rpm -ql redis

yum安装redis的配置文件默认:
/etc/redis.conf

daemonize yes //以守护进程的方式启动,如果以脚本的方式来启动redis,即便这项设为no,也会以守护进程的方式启动,不然以redis-server启动就会占据前台

port 6379 //默认为6379端口

bind 0.0.0.0 //监听端口,这样是监听本机所有地址

tcp-backlog 511 // tcp-backlog的长度

unixsocket /tmp/redis.sock //也可以使用sock的方式进行通信

unixsocketperm 700 //sock 文件的访问权限

timeout 0 //设置客户端连接超时时间,一个客户端连接空闲多长时间以后让他超时,0表示禁用此功能,客户端连接不超时

pidfile /var/run/redis_6379.pid //pid文件

logfile /var/log/redis/redis.log //日志文件

databases 16 //默认我们把所有数据都放在0号数据库中,

#   save ""     //持久化存储的频率,为空表示禁用

save 900 1
save 300 10
save 60 10000

redis的启动脚本: /etc/rc.d/init.d/redis

启动redis的方式:

    service  redis start

    # redis-server /etc/redis.conf

检查启动的结果:

    [root@linux-node1 ~]# ss -tnl | grep 6379
    LISTEN     0      128                       *:6379                     *:*     

客户端: redis-cli

[root@linux-node3 ~]# redis-cli -h 10.0.0.9 -p 6379
10.0.0.6:6379>

三、Redis持久化

    Redis数据是工作在内存中,无论是否实现持久化,数据都是存储在内存中的,如果数据不重要就可以不用持久化,如果数据非常重要就必须实现其持久化。

两种机制的持久化:RDB和AOF(Appending Only File)

    RDB是一种快照机制,按照某周策略周期性的将数据写入到磁盘中,数据文件默认为:dumo.rdb,这种持久化的缺点是可能数据会不完整,因为它的这种持久化是有时间差的。

    AOF从本质上来讲就是将redis每一个操作的命令,都以顺序IO的方式附加在指定文件的尾部,记录每一个redis的写操作命令,类似于mysql的binlog机制。但是这种持久化也有缺点:因为以追加的方式向文件中写数据,文件会越来越大,而且有些命令是冗余的,AOF的重写机制可以解决这种问题。

RDB: 

        vim /etc/redis.conf

        SAVE 900 1
        SAVE 300 10
        SAVE 60 10000

        SAVE ""     //关闭RDB功能

        stop-writes-on-bgsave-error yes
        rdbcompression yes
        rdbchecksum yes
        dbfilename  dump.rdb
        dir /var/lib/redis

AOF:

        vim /etc/redis.conf

        appendonly no       //默认为没有开启aof功能

        appendfilename  "appendonly.aof"    //aof文件

        # appendfsync always    //每次收到写命令就写入磁盘的aof文件,这种方式最安全,但是会有大量的io,影响性能         
        appendfsync everysec    //每秒将写命令写入磁盘aof文件,这是在性能和持久化二者之间做了一个折中的操作,是推荐使用的方式
        # appendfsync no    //append的功能不会触发写操作,所有写操作都是提交给os,由操作系统自行决定是如何写入磁盘

        no-appendfsync-on-rewrite no    //在重写时对新写的操作不做fsync,而是暂存在内存中,如果确保内存足够可高,建议写成yes,以提升起性能

        auto-aof-rewrite-percentage 100     //当前的aof文件是上次重写时的1倍时,就开始aof文件的重写
        auto-aof-rewrite-min-szie 64mb      //当aof文件超过64mb时才重写aof文件,如果小于64mb,即使当前aof文件是上次重写时的一倍时也不会重写,否则文件重写频繁了

注意:上述配置也可以在命令行中设置"CONFIG SET XXX",但是在命令行中配置只对当前进程有效,如果想一直生效,就必须使用 CONFIG REWRITE命令,将配置写入到配置文件中去。

示例:
        [root@linux-node1 ~]# redis-cli
        127.0.0.1:6379> CONFIG SET appendonly yes   //表示开启aof功能

特别强调: 持久并不能取代数据备份,还应制定备份策略,对redis数据库进行定期备份,如果我们同时启动了RDB和AOF功能,如果RDB正在创建快照,并且其他条件也触发了AOF重写,这个时候对磁盘的IO影响非常大,一般而言redis会自动禁止这种情况发生,也就是说BGSAVE的过程中,对应的BGREWRITEAOF不会执行,反之也亦然。如果BGSAVE正在执行,用户自己手动执行了BGREWRIGEAOF命令,这个时候服务器会向用户返回一个OK,并告诉用户请求已收到,但是不服务器不会执行这个命令,服务器会等BGSAVE完成以后再来执行BGREWRITEAOF命令。

RDB和AOF同时启动时:
1、redis的RBD和AOF重写是不能同时进行的
2、在redis服务器启动时用于恢复数据时,会优先使用AOF

四、Redis 复制(replication)

特点:
一个Master可以有多个slave
支持链式复制

    Master 以非阻塞方式同步数据只slave,这也就意味着master会继续处理一个或多个请求,我们可以只放master进行写操作,slave端进行读操作,  当用户向主服务器端写数据时,redis通过sync机制,将数据发往slave,slave也会执行相同的操作,也就是说master可以有多个slave,一个slave也可以是其他slave的master,这样就实现了链式复制。

    启动一个slave后,slave会向master发送一个sync命令,请求同步主库上的数据,无论slave是第一次连接还是重新连接,master都会启动一个后台子进程,将数据快照保存至数据文件中,把数据文件发送给slave,slave收到数据文件后会保存到本地,并将文件的数据载入到内存中,以实现数据在slave端的重建,实现数据的复制。

    node1: 10.0.0.6       master
    node2: 10.0.0.7       slave
    node3: 10.0.0.8       slave

配置主从复制很简单:

        slave: vim /etc/redis.conf
        vim /etc/redis.conf    //rpm包安装的路径,源码安装路径有所不同

        slaveof MASTER_IP MASTER_PORT

        slave: 命令行接口        

        > SLAVEOF host port

    执行过程:

    node1:
            [root@linux-node1 ~]# service redis start
            启动 :                                                    [确定]

            [root@linux-node1 ~]# redis-cli -h 10.0.0.6 -p 6379
            10.0.0.6:6379> 
            127.0.0.1:6379> info replication
            # Replication
            role:master
            connected_slaves:0         //还没有slave加入进来
            master_repl_offset:99
            repl_backlog_active:1
            repl_backlog_size:1048576
            repl_backlog_first_byte_offset:2
            repl_backlog_histlen:98

    node2:
            [root@linux-node2 ~]# redis-server /usr/local/redis/redis.conf 
            [root@linux-node2 ~]# redis-cli
            127.0.0.1:6379> 

            127.0.0.1:6379> info replication
            # Replication
            role:master
            connected_slaves:0
            master_replid:608f508dfbc0ae2684af034e53083b7e2bb664d7
            master_replid2:0000000000000000000000000000000000000000
            master_repl_offset:0
            second_repl_offset:-1
            repl_backlog_active:0
            repl_backlog_size:1048576
            repl_backlog_first_byte_offset:0
            repl_backlog_histlen:0
            127.0.0.1:6379> SLAVEOF 10.0.0.9 6379
            OK
            127.0.0.1:6379> info replication
            # Replication
            role:slave
            master_host:10.0.0.9
            master_port:6379
            master_link_status:up
            master_last_io_seconds_ago:7
            master_sync_in_progress:0
            slave_repl_offset:449
            slave_priority:100
            slave_read_only:1
            connected_slaves:0
            master_replid:ea8c42a38cb835dce9fa02d1dcc367f6e54d3d4e
            master_replid2:0000000000000000000000000000000000000000
            master_repl_offset:449
            second_repl_offset:-1
            repl_backlog_active:1
            repl_backlog_size:1048576
            repl_backlog_first_byte_offset:450
            repl_backlog_histlen:0

    再在node1上检查:

        127.0.0.1:6379> info replication
        # Replication
        role:master
        connected_slaves:1                                                                    //可以看到slave的信息
        slave0:ip=10.0.0.16,port=6379,state=online,offset=547,lag=0
        master_repl_offset:547
        repl_backlog_active:1
        repl_backlog_size:1048576
        repl_backlog_first_byte_offset:2
        repl_backlog_histlen:546

测试主从:

node1:

    127.0.0.1:6379> SET student jerry
    OK
    127.0.0.1:6379> GET student
    "jerry"

node2:

    127.0.0.1:6379> GET student
    "jerry"

五、sentinel实现master的高可用

配置文件: /etc/redis-sentinel.conf

        vim /etc/redis-sentinel.conf

        port 26379    //默认监听端口

        # sentinel monitor <master-name> <ip> <redis-port> <quorum>    //这项最重要,指明监控的master
        sentinel monitor mymaster 10.0.0.6 6379 2

        # Default is 30 seconds.        //sentinel认为服务器不在线最少经过的秒数,判断某节点不在线的超时时间,默认为毫秒
        sentinel down-after-milliseconds mymaster 30000 

     # sentinel parallel-syncs <master-name> <numslaves>        //指定了在执行故障转移时,最多可以有多少个从服务器对新主服务器进行同步

     entinel parallel-syncs mymaster 1

     # sentinel failover-timeout <master-name> <milliseconds>    //故障转移超时时长,也就是说master故障时,把一个slave提升为master的最长时间

     # Default is 3 minutes.
     sentinel failover-timeout mymaster 180000

    示例:三个节点(1个master节点,2 slave节点,1 sentinel)

    node1:  master    10.0.0.6
    node2:  slave       10.0.0.7
    node3 : slave       10.0.0.8

    在 node1, node2, node3安装redis(需要有epel源)

    # yum -y install redis 

    在node1, node2, node3修改配置文件

    # vim /etc/redis.conf

    daemonize  yes    //以守护进程的方式启动

    bind 0.0.0.0     //监听在本机的所有地址

    启动node1, node2,node3 redis,还没有设置主从复制

    node1:

            [root@linux-node1 ~]# redis-server /etc/redis.conf
            [root@linux-node1 ~]# ss -tnl | grep redis-server
            [root@linux-node3 ~]# ss -tnl | grep 6379
            LISTEN     0      128                       *:6379                     *:*    
            [root@linux-node1 ~]# redis-cli
            127.0.0.1:6379> INFO replication
            # Replication
            role:master
            connected_slaves:0
            master_repl_offset:0
            repl_backlog_active:0
            repl_backlog_size:1048576
            repl_backlog_first_byte_offset:0
            repl_backlog_histlen:0
            127.0.0.1:6379> 

    node2:                                                         //这个是CentOS 7下手动源码安装的 redis-4.0.10,这个没有没有影响

            [root@linux-node2 ~]# redis-cli
            127.0.0.1:6379> INFO replication
            # Replication
            role:master
            connected_slaves:0
            master_replid:6678af3be5f3af43963f5018fc767c8991945239
            master_replid2:0000000000000000000000000000000000000000
            master_repl_offset:0
            second_repl_offset:-1
            repl_backlog_active:0
            repl_backlog_size:1048576
            repl_backlog_first_byte_offset:0
            repl_backlog_histlen:0
            127.0.0.1:6379> 

    node3:
            [root@linux-node3 ~]# redis-cli
            127.0.0.1:6379> INFO replication
            # Replication
            role:master
            connected_slaves:0
            master_repl_offset:0
            repl_backlog_active:0
            repl_backlog_size:1048576
            repl_backlog_first_byte_offset:0
            repl_backlog_histlen:0
            127.0.0.1:6379> 

    设置主从:设置node2,node3为slave

        node2:

        > CONFIG SLAVEOF 10.0.0.6

        node3:

        > CONFIG SLAVEOF 10.0.0.8

    验证主从:

        node1:

                [root@linux-node3 ~]# redis-cli
                127.0.0.1:6379> INFO replication
                # Replication
                role:master                                                   //master
                connected_slaves:0
                master_repl_offset:0
                repl_backlog_active:0
                repl_backlog_size:1048576
                repl_backlog_first_byte_offset:0
                repl_backlog_histlen:0
                127.0.0.1:6379> INFO replication
                # Replication
                role:master
                connected_slaves:2
                slave0:ip=10.0.0.7,port=6379,state=online,offset=365,lag=1
                slave1:ip=10.0.0.8,port=6379,state=online,offset=365,lag=0
                master_repl_offset:365
                repl_backlog_active:1
                repl_backlog_size:1048576
                repl_backlog_first_byte_offset:2
                repl_backlog_histlen:364
                127.0.0.1:6379> 

        node2:

            [root@linux-node2 ~]# redis-cli
            127.0.0.1:6379> SLAVEOF 10.0.0.6 6379
            OK
            127.0.0.1:6379> INFO replication
            # Replication
            role:slave                                                                 //slave
            master_host:10.0.0.6
            master_port:6379
            master_link_status:up
            master_last_io_seconds_ago:5
            master_sync_in_progress:0
            slave_repl_offset:57
            slave_priority:100
            slave_read_only:1
            connected_slaves:0
            master_replid:d1c08312fe30d1259d943f1a09bd7aa5b7bebf01
            master_replid2:0000000000000000000000000000000000000000
            master_repl_offset:57
            second_repl_offset:-1
            repl_backlog_active:1
            repl_backlog_size:1048576
            repl_backlog_first_byte_offset:30
            repl_backlog_histlen:28
            127.0.0.1:6379> 

        node3: 
            [root@linux-node3 ~]# redis-cli
            127.0.0.1:6379> SLAVEOF 10.0.0.6 6379
            OK
            127.0.0.1:6379> INFO replication
            # Replication
            role:slave                                                        //slave
            master_host:10.0.0.6
            master_port:6379
            master_link_status:up
            master_last_io_seconds_ago:6
            master_sync_in_progress:0
            slave_repl_offset:253
            slave_priority:100
            slave_read_only:1
            connected_slaves:0
            master_repl_offset:0
            repl_backlog_active:0
            repl_backlog_size:1048576
            repl_backlog_first_byte_offset:0
            repl_backlog_histlen:0
            127.0.0.1:6379> 

    这样我们的主从复制就配置好了,为了进一步验证主从复制,我们在master上写入数据,查看下slave上面的数据情况

            node1:

                    127.0.0.1:6379> SET cache memcached
                    OK
                    127.0.0.1:6379> GET cache
                    "memcached"

            node2:

                    127.0.0.1:6379> GET cache
                    "memcached"

            node3:

                    127.0.0.1:6379> GET cache
                    "memcached"

启动sentinel服务监控master

    为了节约机器,我们把node1设置为sentinel

    修改配置文件: /etc/redis-sentinel.conf

            # vim /etc/redis-sentinel.conf

            port  26379    //默认监听26379端口

            daemonize  yes    //工作在守护进程模式

            sentinel monitor mymaster 10.0.0.6 6379 1    //设置监控的master,因为只有sentinel节点,所以quorum置为1,这个参数必须设置

            sentinel down-after-milliseconds mymaster 5000    //默人为30000,做实验可以设置为时间短一点,5秒以后认为master不在线

            sentinel failover-timeout mymaster 60000    //故障转移多长时间不成功就认为是失败的,默人为180000(3分钟)

            我们就修改这几项,保存退出

启动sentinel: redis-server 或者redis-sentinel

            root@linux-node1 ~]# redis-sentinel /etc/redis-sentinel.conf 
            [root@linux-node1 ~]# ss -tnl | grep 26379
            LISTEN     0      128                       *:26379                    *:*     
            LISTEN     0      128                      :::26379                   :::*    

            root@linux-node1 ~]# redis-server /etc/redis-sentinel.conf --sentinel
            [root@linux-node1 ~]# ss -tnl | grep 26379
            LISTEN     0      128                       *:26379                    *:*     
            LISTEN     0      128                      :::26379                   :::*  

验证sentinel对master的HA

        sentinel节点(node1):

            [root@linux-node1 ~]# redis-cli -h 127.0.0.1 -p 26379
            127.0.0.1:26379> SENTINEL slaves mymaster

            127.0.0.1:26379> SENTINEL masters

下线node1 上的master查看master是否会自动转移,是否会从2个slave中选一个作为master

    127.0.0.1:26379> SENTINEL masters
    1)  1) "name"
            2) "mymaster"
            3) "ip"
            4) "10.0.0.7"                 //可以看出master已经转移

在node2上查看

        127.0.0.1:6379> info replication
        # Replication
        role:master
        connected_slaves:0
        master_repl_offset:0
        repl_backlog_active:0
        repl_backlog_size:1048576
        repl_backlog_first_byte_offset:0
        repl_backlog_histlen:0

让node1上的redis上线,查看主从复制情况,node1上的redis是slave,而不会成为master,因此当一个下线的master重新上线时,也不会成为master,而是slave。

Redis 在CentOS 6上的 安装和部署以及redis的主从复制sentinel实现HA

标签:red   时间   比较   mon   操作   失败   处理   love   star   

原文地址:http://blog.51cto.com/wbilly/2131135

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!