日: 2018年9月5日

  • HAproxyでHR構成を組む on AWS

    HAproxyでHR構成を組む on AWS

    はじめに

    DBサーバへ接続する際、readレプリカを複数台作ることが一般的だが、readレプリカに対してバランシングはインフラの設計ポイントとなる。auroraであれば自動でreadレプリカを作ってくれるのでその考慮は要らないがレガシーなシステムを運用している場合それは使えない。今回はAWSで組むこととする。

    やりたいこと

    多くのプログラムはそうであろう構成。

    プログラムは更新用(write)と参照用(read)で接続先を変え、
    データベースはMasterとSlaveでレプリケーションをしている。

    Slaveは今後増える可能性もあるのに加え、Slaveが1台ダウンしてもサービスが稼働できるようにするには、クラスタリング構成をする必要がある。

    クラスタリングソフトの検討

    名前考察
    keepalived名前解決不可能。また、ググっても実績なし
    HAProxyAmazon linuxでyumでのversionが古い(1.5.2)。v1.6の resolvers オプションを使ってVPCのnameserverを参照するようにし、A Recordの変更に追従させる事が可能だが、ソースからのinstallになってしまう
    MySQL Routerアルファ版 本番利用 非推奨
    Consul by HashiCorpググっても出ない
    ProxySQLAmazonLinux非対応

    keppalivedはAWSでは難しいようだ。

    今回はHA proxyで実現することにした。

    対応

    Amazon linuxの上にHAproxyを使いクラスタリングを実現する。

     

    HAproxyのインストール

    amazon linuxの場合、yumでinstallしようとすると、versionが古い。

    そのため、sourceでインストールすることにした

    yum install -y gcc
    cd /usr/local/src/
    wget http://www.haproxy.org/download/1.8/src/haproxy-1.8.8.tar.gz
    pwd
    tar xvfz haproxy-1.8.8.tar.gz
    ls -ltr
    cd haproxy-1.8.8
    make TARGET=generic
    make install
    

    HAproxyの設定

    設定は以下の通り

    $ cat /etc/haproxy/haproxy.cfg 
    global
        log         tsukada01 local2
    
        chroot      /var/lib/haproxy
        pidfile     /var/run/haproxy.pid
        maxconn     4096
        user        haproxy
        group       haproxy
        daemon
        stats socket /var/lib/haproxy/stats
        stats maxconn 1
        stats timeout 120s
    
    resolvers awsvpc
        nameserver vpc 172.20.0.2:53
    
    defaults
        mode        tcp
        log         global
        retries     3
        timeout     connect 10s
        timeout     client 1m
        timeout     server 1m
        timeout     check 10s
        maxconn     512
    
    listen mysql
        bind tsukada01:3306
        mode tcp
        option mysql-check user haproxy_check
    
        balance roundrobin
    
        option          log-health-checks
    
        server read01 dbserver01:3306 check port 3306 resolvers awsvpc inter 2000 fall 3
        server read02 dbserver02:3306 check port 3306 resolvers awsvpc inter 2000 fall 3

    もう片方のサーバは今の通りに設定した

    $ cat /etc/haproxy/haproxy.cfg
    global
        log         tsukada02 local2
    
        chroot      /var/lib/haproxy
        pidfile     /var/run/haproxy.pid
        maxconn     4096
        user        haproxy
        group       haproxy
        daemon
        stats socket /var/lib/haproxy/stats
        stats maxconn 1
        stats timeout 120s
    
    resolvers awsvpc
        nameserver vpc 172.20.0.2:53
    
    defaults
        mode        tcp
        log         global
        retries     3
        timeout     connect 10s
        timeout     client 1m
        timeout     server 1m
        timeout     check 10s
        maxconn     512
    
    listen mysql
        bind tsukada02:3306
        mode tcp
        option mysql-check user haproxy_check
    
        balance roundrobin
    
        option          log-health-checks
    
        server read01 dbserver01:3306 check port 3306 resolvers awsvpc inter 2000 fall 3
        server read02 dbserver02:3306 check port 3306 resolvers awsvpc inter 2000 fall 3

    ほとんど同じように見えるので差分をまとめると、以下のような違いだ

    これで

    • tsukada001の3306ポート
    • tsukada002の3306ポート

      に接続すると、dbserver01,dbserver02へラウンドロビンで接続されるようになった

    しかし、これでは当然tsukada001、tsukada002自体で障害が起きる可能性もある。

    ALBでバランシング

    tsukada001:3306、tsukada002:3306をALBに登録しラウンドロビンで登録した。

    これによりALBのエンドポイントが払い出され、それを各プログラムが参照するような形にして可用性を担保した。

    振り返って見て思うこと

    レガシーなDBでこの構成を組もうとすると、できないことはないが、登場人物がやたら多い。一番なのはauroraなどに移行し、本当に必要なことのみに集中できれば最高だ。