Назад | Перейти на главную страницу

Балансировка нагрузки MySQL. Тайм-аут резервного сервера

Уважаемые, любимые люди на ServerFault. Я пытаюсь (и не могу) настроить массив серверов MySQL с балансировкой нагрузки. Пожалуйста, просветите меня, покажите мне ошибку в моем пути.

Текущая настройка: два сервера MySQL с выделенными фиксированными IP-адресами (10.116.219.47 и 10.116.219.48) и один виртуальный IP-адрес, который используется совместно с keepalived (10.116.219.12). Эта установка успешно обеспечивает аварийное переключение. DB2-сервер быстро вступит во владение, если мы отключим DB1-сервер. Только при добавлении блока virtual_server в конфигурацию все начинает ломаться.

DB1

vrrp_instance VI_2 {
    state MASTER

    interface eth0
    virtual_router_id 60
    priority 150

    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 3S83hbt200SbwY6
    }
    virtual_ipaddress {
        10.116.219.12
    }
}

DB2

vrrp_instance VI_2 {
    state BACKUP

    interface eth0
    virtual_router_id 60
    priority 100

    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 3S83hbt200SbwY6
    }
    virtual_ipaddress {
        10.116.219.12
    }
}

Мы пытались добавить балансировку нагрузки в конфигурацию keepalived, но здесь DB2 перестает отвечать.

virtual_server 10.116.219.12 3306 {
  delay_loop 2
  lb_algo rr
  lb_kind DR
  protocol TCP

  real_server 10.116.219.47 3306 {
    weight 10
    TCP_CHECK {
      connect_port    3306
      connect_timeout 1
    }
  }

  real_server 10.116.219.48 3306 {
    weight 10
    TCP_CHECK {
      connect_port    3306
      connect_timeout 1
    }
  }
}

Попытка подключиться к виртуальному ip (10.116.219.12) будет чередоваться при успешном ответе от DB1 или тайм-ауте от DB2.

На данный момент отладка:

Таким образом, похоже, что сервер MySQL MySQL отказывается отвечать, я предполагаю, что место назначения входящего пакета (общий виртуальный IP-адрес) не известно серверу DB2, потому что DB1 передает его как ведущее устройство поддержки активности.

Поскольку вы используете прямую маршрутизацию, виртуальный IP-адрес необходимо настроить на обоих серверах одновременно. Вы можете добиться этого, имея второй экземпляр vrrp, который настраивает VIP (10.116.219.12) на интерфейсе обратной связи вторичного сервера. Когда соединение перенаправляется от балансировщика нагрузки на вторичный сервер, он будет отвечать на eth0 как обычно.

Если вы сделаете это, вам нужно будет отключить маршрутизацию от источника через sysctl. Например:

# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0

Кроме того, вам необходимо изменить способ объявления ARP и ответа на запросы (больше информации):

net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.eth0.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2

Также настройте фильтрацию rp:

net.ipv4.conf.eth0.rp_filter = 1 # Works for CentOS 5
or
net.ipv4.conf.eth0.rp_filter = 2 # Works for CentOS 6+

Параметр rp_filter по умолчанию может варьироваться в зависимости от версии ядра, поэтому убедитесь, что вы выбрали правильный параметр. Больше информации.

Чтобы расширить ответ Джина и получить jnovack, который "не утерян", на CentOS 7 у меня сработало следующее:

  • На обоих серверах MySQL создайте файл /etc/sysconfig/network-scripts/ifcfg-lo:1 содержащий

    DEVICE=lo:1
    BOOTPROTO=static
    ONBOOT=yes
    IPADDR=***your keepalived virtual IP***
    NETMASK=255.255.255.255
    
  • На обоих серверах MySQL настройте sysctl с помощью (не забудьте sysctl -p перезагрузить)

    net.ipv4.ip_nonlocal_bind=1
    net.ipv4.ip_forward=1
    net.ipv4.conf.default.arp_ignore=1
    net.ipv4.conf.default.arp_announce=2
    net.ipv4.conf.all.arp_ignore=1
    net.ipv4.conf.all.arp_announce=2
    net.ipv4.conf.default.rp_filter=0
    net.ipv4.conf.all.rp_filter=0
    net.ipv4.tcp_syncookies=1
    net.ipv4.conf.all.log_martians=1
    net.ipv4.conf.lo.arp_ignore=1
    net.ipv4.conf.lo.arp_announce=2
    
  • Перезапустите сетевую службу

    systemctl restart network
    # service network restart on CentOS 6
    

(вы можете проверить свой новый виртуальный интерфейс при выполнении loopback ifconfig)

  • Перезапустите keepalived служба

    systemctl restart keepalived
    # service keepalived restart on CentOS 6