• redis高可用之DNS篇


    1.  背景

    例如,存在一套redis主从(主从节点在不同的主机上),应用程序通过主库的ip进行读写操作。 但是,主库一旦出现故障,虽然有从库,且从库提升为主库,但是应用程序如果想使用从库则必须修改配置,重启应用方可生效。如用此情况,则涉及的人员比较多,且应用程序恢复使用的时间比较长。对于此情况,可以采取以下2种解决方式解决:

    a)  配置VIP

    在Redis主库服务器上配置vip,当主库出现问题时,配置脚本将vip自动切换至从节点,并将从节点提升为读写状态。应用程序中配置的是vip,主库异常时,从库自动提升为主库对外提供服务,应用程序无需做任何操作。

    b)  使用DNS

    应用程序通过配置内网域名连接redis,DNS服务器对应域名映射到redis主库服务器IP。 当redis主库异常时,将redis从节点提升为读写主库,修改DNS域名映射关系至redis从节点ip,此时应用程序也无需进行操作。

    注:

    以上2种方式均存在缺陷,例如:

    • vip方式存在问题:  当主从节点不在同一个机房或同一网段时,将无法使用相同的vip。
    • DNS方式: 使用DNS方式将有DNS缓存问题,即修改域名映射后域名仍可能解析到原主库机器的ip。

    vip配合哨兵的高可用方式将在后续介绍,本次先介绍DNS服务器配置及dns方式解决方案。

    2.  DNS服务配置

    2.1  安装DNS服务

    # 安装bind相关工具
    yum  install  bind  bind-utils  bind-devel bind-libs  bind-chroot  -y

    2.2  修改配置文件

    vim /etc/named.conf
    ##  编译对应内容
    // named.conf
    //
    // Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
    // server as a caching only nameserver (as a localhost DNS resolver only).
    //
    // See /usr/share/doc/bind*/sample/ for example named configuration files.
    //
    
    options {
    //      listen-on port 53 { 127.0.0.1; };       // 此行注释
            listen-on port 53 { any; };             //  添加此行
            listen-on-v6 port 53 { ::1; };
            directory       "/var/named";
            dump-file       "/var/named/data/cache_dump.db";
            statistics-file "/var/named/data/named_stats.txt";
            memstatistics-file "/var/named/data/named_mem_stats.txt";
    //      allow-query     { localhost; };        //  注释此行
            allow-query     { any; };              //  添加此行
            forwarders {114.114.114.114; };          //   添加此行,这是在DNS服务器不知道域名解析的时候询问这个IP的主机,这个IP的主机必须联网
            recursion yes;
    
            dnssec-enable yes;
            dnssec-validation yes;
    
            /* Path to ISC DLV key */
            bindkeys-file "/etc/named.iscdlv.key";
    
            managed-keys-directory "/var/named/dynamic";
    };
    
    logging {
            channel default_debug {
                    file "data/named.run";
                    severity dynamic;
            };
    };
    
    zone "." IN {
            type hint;
            file "named.ca";
    };
    
    include "/etc/named.rfc1912.zones";
    include "/etc/named.root.key";

    2.3   检查语法

    named-checkconf

    2.4   启动DNS服务

    /etc/init.d/named  start

    2.5  配置DNS正向解析文件

    a)  在/etc/named.rfc1912.zones添加正向解析配置

    vim /etc/named.rfc1912.zones  # 此文件名在上面步骤的/etc/named.conf文件末尾有指定
    
    ##  此文件末尾追加如下内容
    
    
    zone "redis.com" IN {                         //  redis.com 名自定义,即需要解析的域名
            type master;                          //  dns域类型为master
            file "redis.com.zone";                //  redis.com.zone 文件名自定义,后续文件名需与此一致
            allow-update { none; };
    };

    b)  根据上一步的情况,配置解析文件

    # 拷贝文件
    cp -p  named.localhost redis.com.zone  # 拷贝文件,注意要连同权限一起拷贝,因权限不一致,启动会报错
    
    vim   redis.com.zone 
    
    $TTL 1D
    @       IN SOA  www.redis.com.  rname.invalid. (
                                            0       ; serial
                                            1D      ; refresh
                                            1H      ; retry
                                            1W      ; expire
                                            3H )    ; minimum
            NS      www.redis.com.
    
    dns  IN A 192.168.56.208
    www  IN A 192.168.56.208

    2.6  配置DNS反向解析文件

    a)  在/etc/named.rfc1912.zones添加反向解析配置

    可以将正向解析与反向解析配置在一个文件里,即file配置为相同的文件名。本次分开配置来演示

    vim /etc/named.rfc1912.zones  # 此文件名在上面步骤的/etc/named.conf文件末尾有指定
    
    ##  此文件末尾追加如下内容
    
    zone "56.168.192.in-addr.arpa" IN {   
            type master;
            file "redis.com.local";
            allow-update { none; };
    };

    b)   根据上一步的情况,配置解析文件

    # 拷贝文件
    cp -p  named.localhost redis.com.local  # 拷贝文件,注意要连同权限一起拷贝,因权限不一致,启动会报错
    
    vim   redis.com.local
    
    $TTL 1D
    @       IN SOA  www.redis.com.  rname.invalid. (
                                            0       ; serial
                                            1D      ; refresh
                                            1H      ; retry
                                            1W      ; expire
                                            3H )    ; minimum
            NS      @
            A       192.168.56.208
            AAAA    ::1
    208     IN PTR www.redis.com.

    2.7  重启DNS服务

    /etc/init.d/named restart

    2.8  测试DNS服务器

    在另一台主机上测试DNS是否可用,操作步骤如下。

    # 修改域名解析文件
    vim /etc/resolv.conf
    
    # 将创建的DNS服务器地址添加至此文件
    nameserver   192.168.56.209

     正向解析测试

     nslookup www.redis.com
    # 结果如下
    Server:        192.168.56.209
    Address:    192.168.56.209#53
    
    Name:    www.redis.com
    Address: 192.168.56.208

    反向解析测试

    nslookup  192.168.56.208
    #  结果如下:
    Server:        192.168.56.209
    Address:    192.168.56.209#53
    
    208.56.168.192.in-addr.arpa    name = www.redis.com.

     ping 域名测试

     ping  www.redis.com
    #  结果如下
    PING www.redis.com (192.168.56.208) 56(84) bytes of data.
    64 bytes from www.redis.com (192.168.56.208): icmp_seq=1 ttl=64 time=0.229 ms
    64 bytes from www.redis.com (192.168.56.208): icmp_seq=2 ttl=64 time=0.287 ms
    64 bytes from www.redis.com (192.168.56.208): icmp_seq=3 ttl=64 time=0.276 ms
    64 bytes from www.redis.com (192.168.56.208): icmp_seq=4 ttl=64 time=0.224 ms

    至此,DNS服务器搭建并测试完毕,下面进入正题。

    3.  搭建Redis主从

     关于redis搭建之前的文章已经介绍过,详细信息可参考历史文章https://www.cnblogs.com/gjc592/p/11098047.html。

    3.1  搭建主、从节点redis实例,部署过程完全一致

    a)  依赖包安装

    yum -y install cpp binutils glibc glibc-kernheaders glibc-common glibc-devel gcc make gcc-c++ libstdc++-devel tcl

    b)  安装包准备

    可以从官网  https://redis.io下载最新版redis

    wget  http://download.redis.io/releases/redis-4.0.14.tar.gz  
    tar -zxvf redis-4.0.14.tar.gz

    c)   编译、安装

    cd   redis-4.0.14
    make 
    make install

    d) 创建目录、修改配置文件、启动redis

    建议创建单独的redis目录

    #  创建目录
    mkdir -p /data/redis/redis6379
    
    #  拷贝配置文件
    cp redis.conf  /data/redis/redis6379/
    
    #  修改配置文件
    vim redis.conf
    修改如下部分
    bind  0.0.0.0     可以指定所有地址均可访问,若指定对应网段或IP 修改此处即可
    daemonize yes   放在后台执行,建议修改为yes
    pidfile /data/redis/redis6379/redis_6379.pid  指定pid文件目录及文件名
    logfile "/data/redis/redis6379/redis6379.log" 指定log文件目录及文件名

    # 其他参数在生产环境中可适当调整

    # 启动redis
    redis-server redis.conf

     3.2  配置主从

    在从服务器执行如下命令配置主从

    127.0.0.1:6379> slaveof   192.168.56.208  6379    ##  即输入对应的redis主库的ip 即端口

    查看主从状态

    127.0.0.1:6379> info Replication
    ## 结果如下 # Replication role:slave master_host:
    192.168.56.208 master_port:6379 master_link_status:up // up代表已正常同步 master_last_io_seconds_ago:3 master_sync_in_progress:0 slave_repl_offset:266 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:22830eb406e63f0a85d3d912a44e1b80dba6c860 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:266 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:266

    至此,redis主从同步配置完成

    4.  测试域名方式操作redis

    编写程序,测试使用域名方式连接redis

    注意:程序运行机器需添加对应的内网DNS服务器,即2.8中的操作。本次使用python进行测试

    4.1  安装Python所需的包-- redis

    python连接redis需安装redis包,关于Python升级,pip安装等历史文章里均有,如有需要可以参考操作

    pip  install redis

    4.2  编写简单的Python操作redis的测试程序

     vim test_redis.py 
    
    #  内容如下
    
    #!/usr/bin/python
    # coding=utf-8
    
    import redis
    v_ip ='www.redis.com'
    v_port = 6379
    v_passwd=''
    r = redis.Redis(host=v_ip,port=v_port,password=v_passwd,db=0)
    r.set('test_key1','test1')
    result = r.get('test_key1')
    print  result ,"设置键成功并获取到values"
    r.delete('test_key1')
    print  "删除键完毕"
    result1 = r.get('test_key1')
    print result1,"验证删除成功"

    4.3   运行测试程序,看是否能通过域名操作成功

     python test_redis.py 
    # 结果如下
    test1 设置键成功并获取到values
    删除键完毕
    None 验证删除成功

    有图有真相

    说明,使用域名操作redis正常。

    5.  模拟redis主库异常

    5.1  关闭主库

    127.0.0.1:6379> shutdown
    not connected> exit

    5.2  测试程序使用redis情况

    python test_redis.py 
    ##  报错
    Traceback (most recent call last):
      File "test_redis.py", line 9, in <module>
        r.set('test_key1','test1')
      File "/usr/local/python2.7/lib/python2.7/site-packages/redis/client.py", line 1451, in set
        return self.execute_command('SET', *pieces)
      File "/usr/local/python2.7/lib/python2.7/site-packages/redis/client.py", line 772, in execute_command
        connection = pool.get_connection(command_name, **options)
      File "/usr/local/python2.7/lib/python2.7/site-packages/redis/connection.py", line 994, in get_connection
        connection.connect()
      File "/usr/local/python2.7/lib/python2.7/site-packages/redis/connection.py", line 497, in connect
        raise ConnectionError(self._error_message(e))
    redis.exceptions.ConnectionError: Error 111 connecting to www.redis.com:6379. Connection refused.

    即,此时redis已无法使用

    5.3   提升从库为读写库

    从库默认为只读,断开主从复制后将会变为读写库

    a)  查看此时从库复制状态

    127.0.0.1:6379> info Replication
    # Replication
    role:slave
    master_host:192.168.56.208
    master_port:6379
    master_link_status:down                       // 主从同步已断开
    master_last_io_seconds_ago:-1
    master_sync_in_progress:0
    slave_repl_offset:3215
    master_link_down_since_seconds:98
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_replid:22830eb406e63f0a85d3d912a44e1b80dba6c860
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:3215
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:3215

    b)  断开主从同步

    127.0.0.1:6379> slaveof  no one
    OK
    127.0.0.1:6379> info Replication
    # Replication
    role:master                                             // 断开后,已变成主库
    connected_slaves:0
    master_replid:180df5fbdc8cf8999b27ad42e6c57eb3be31b6b2
    master_replid2:22830eb406e63f0a85d3d912a44e1b80dba6c860
    master_repl_offset:3215
    second_repl_offset:3216
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:3215

    因此时域名仍指向原主库,所以程序依旧异常。

    6. 切换域名指向

    6.1 修改配置文件

    将DNS服务中对应域名的IP地址改为从库地址

     vim redis.com.zone 
    ##  修改
    $TTL 1D
    @       IN SOA  www.redis.com. rname.invalid. (
                                            0       ; serial
                                            1D      ; refresh
                                            1H      ; retry
                                            1W      ; expire
                                            3H )    ; minimum
            NS      www.redis.com.
    
    dns  IN A 192.168.56.207
    www  IN A 192.168.56.207

    vim redis.com.local
    # 修改后
    $TTL 1D
    @       IN SOA  www.redis.com. rname.invalid. (
                                            0       ; serial
                                            1D      ; refresh
                                            1H      ; retry
                                            1W      ; expire
                                            3H )    ; minimum
            NS      @
            A       192.168.56.207
            AAAA    ::1
    207     IN PTR www.redis.com.

    6.2  重启DNS服务或刷新缓存

    本次测试直接重启DNS服务

    /etc/init.d/named  restart

    6.3  简单测试域名解析情况

    nslookup www.redis.com   #正向测试DNS
    # 结果如下
    nslookup www.redis.com
    Server:        192.168.56.209
    Address:    192.168.56.209#53

    Name:    www.redis.com
    Address: 192.168.56.207

    说明已修改成功

    7.  最终测试

    再次使用python 程序测试操作redis情况

    python test_redis.py 
    # 运行结果
    test1 设置键成功并获取到values
    删除键完毕
    None 验证删除成功

    此时应用程序未做任何修改,可以正常使用。

    ps:

    以上测试步骤中部分有省略,如果错误,欢迎指正。

    耿小厨已开通个人微信公众号,想进一步沟通或想了解其他文章的同学可以关注我

  • 相关阅读:
    c++MMMMM:oo
    pytorch简单框架
    第95:PCA
    P1:天文数据获取
    深度学习常用函数记录(tensorflow)
    流畅的python(一)序列构成的数组
    tensorflow2.0学习笔记(一)
    BiseNet阅读总结
    DenseASPP论文总结
    论文写作总结
  • 原文地址:https://www.cnblogs.com/gjc592/p/11341979.html
Copyright © 2020-2023  润新知