It-e.RU
Цифровой двигатель вашего бизнеса.

Отказоустойчивость данных в FreeBSD c помощью HAST.

Отказоустойчивость данных в FreeBSD c помощью HAST.

HAST (Highly Available Storage) позволяет решить задачи прозрачного физического дублирования блочных устройств разделенных машин посредством передачи данных по сети tcp/ip. Диск главного устройства доступен в директории /dev/hast. На практике, это выглядит примерно так: первая машина работает с блочным устройством /dev/hast/XXX, hastd при этом все изменения передает на ведомую машину в соответствующее устройство, например, /dev/YYY. При этом при отключении ведущей машины, на ведомой машине можно смонтировать устройство /dev/hast/XXX и продолжить работу.


HAST (Highly Available Storage) позволяет решить задачи прозрачного физического дублирования блочных устройств разделенных машин посредством передачи данных по сети tcp/ip. Диск главного устройства доступен в директории /dev/hast. На практике, это выглядит примерно так: первая машина работает с блочным устройством /dev/hast/XXX, hastd при этом все изменения передает на ведомую машину в соответствующее устройство, например, /dev/YYY. При этом при отключении ведущей машины, на ведомой машине можно смонтировать устройство /dev/hast/XXX и продолжить работу.

Получается, что у нас возможность создать raid1 по сети. Рассмотрим возможность автоматизации процессов по обеспечению высокой доступности данных. Рекомендую ознакомиться с предыдущей заметкой о обеспечении высокой доступности виртуального сетевого адреса системы. Приступим к созданию хранилища HAST.

Создадим файл /etc/hast.conf на обеих системах:
resource data {
        on carp0 {
                local /dev/ada0p3
                remote 192.168.12.57
        }
        on carp0 {
                local /dev/ada0p3
                remote 192.168.12.56
        }
}
Рассмотрим структуру файла:
  • resource data - создаю ресурс с названием DATA, разумеется можно иначе. Ресурсов может быть много.
  • on carp0 - указываю на каком сетевом интерфейсе работает передача данных
  • local /dev/ada0p3 - указываю с каким устройством будет работать HAST на локальной системе
  • remote 192.168.12.57 - указываю адрес удаленного HAST
  • далее все повторяется, только для удаленной машины, то есть зеркально
  • Теперь запустим демона: /etc/rc.d/hastd start, если он прописан у вас в /etc/rc.conf, /etc/rc.d/hast onestart, если не прописан, или просто /sbin/hastd. После запуска можно будет посмотреть состояние устройст, указанных в конфигурациооном файле. следующей командой: hastctl status. Получим подобный вывод:
    data:
      role: init
      provname: data
      localpath: /dev/ada0p3
      extentsize: 0 (0B)
      keepdirty: 0
      remoteaddr: 192.168.12.57
      replication: fullsync
      dirty: 0 (0B)
      statistics:
        reads: 0
        writes: 0
        deletes: 0
        flushes: 0
        activemap updates: 0
    
    В вашем случае состояние поля role будет init. Проделайте тоже самое на второй машине.
    Теперь назначим первую машину ведущей:
    hastctl role primary RECOURCE 
    
    на второй машине выполним
    hastctl role secondary RECOURCE
    
    Теперь снова смотрим статус и должны увидеть, что на первой машине поле role стало primary:
    data:
      role: primary
      provname: data
      localpath: /dev/ada0p3
      extentsize: 2097152 (2.0MB)
      keepdirty: 64
      remoteaddr: 192.168.12.57
      replication: fullsync
      status: degraded
      dirty: 4194304 (4.0MB)
      statistics:
        reads: 0
        writes: 0
        deletes: 0
        flushes: 0
        activemap updates: 0
    
    на второй secondary:
    data:
      role: secondary
      provname: data
      localpath: /dev/ada0p3
      extentsize: 2097152 (2.0MB)
      keepdirty: 0
      remoteaddr: 192.168.12.56
      replication: fullsync
      status: complete
      dirty: 0 (0B)
      statistics:
        reads: 0
        writes: 32
        deletes: 0
        flushes: 0
        activemap updates: 0
    
    Очень важно, чтобы при этом поле status было с значение complete. Если у вас поле status не имеет значения complete продолжать не стоит, необходимо добиться, чтобы поле status имело значение complete. Просмотрите файл /var/log/messages, там будет указана причина невозможности соединения с соседней системой. Чаще всего проблемы имеют сетевой характер или по причине неверно сконфигурированных блочных устройств. Теперь когда поле status имеет значение complete, наши блочные устройства синхронизированны, можно создать фс и смотнировать. Например, так:
    newfs -U -L -O 2 /dev/hast/data
    mount -t ufs /dev/hast/data /data
    
    При этом вы увидите дисковую активность на второй системе. Теперь вы имеете дубликат блочного устройства первой системы. Можно провести простой тест: на первой системе:
    dd if=/dev/zero of=/data/system1.dd bs=1m count=500
    umount /data
    poweroff
    
    на второй системе:
    hastctl role primary data
    fsck /dev/hast/data
    mount /dev/hast/data /data
    
    Обратите внимание, что при назначении primary роли, устройство /dev/hast/XXX появляется не сразу. Это очень важно! Если вы все правильно сделали, тогда на второй системе у вас устройство смонтируется и вы сможете увидеть файл, созданный на первой машине. Можно создать файл для проверки синхронизации с первой машиной. Теперь при включении первой системы, вам необходимо назначить ей роль secondary для синхронизации изменений в фс, сделанных на второй машине. При этом увидите дисковую активность. Теперь можно отключить вторую систему и дать роль primary первой системе, смонтировать и увидеть файлы, созданные на второй системе. На этом все.

    Теперь автоматизируем процесс. Напишем скрипт, состоящий из 3х частей: 1 часть - up - перевод системы в состояние primary, 2 часть - down - перевод системы в состояние secondary, 3 часть - boot - определение своего состояния при загрузке. Поясню: при загрузке системы, устройству carp назначается высокий приоритет (200) и через некоторое время скрипт определяем состояние этого устройства. Если оно стало MASTER, значит текущая система главная и блочное устройство должно быть в состоянии primary. Если оно BACKUP, то запустить все устройства в состоянии secondary. При отключении ведущей системы через подсистему devd, переводим ведомую систему в ведущую, при этом приоритет устройства carp понижается (станет 10). То есть при загрузке бывшей ведущей системы, скрипт даст устройству carp более высокий приоритет (200) и оно не сможет стать MASTER, при этом скрипт попросит HAST дать своим ресурсам роль secondary. Скрипт, не совершенен, например, в ситуации когда система 1 загрузилась быстрее системы 2, в то время когда система 2 была ведущей. Возможно это получится решить...

    Вот текст скрипта:

    #!/bin/sh
    
    export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
    
    state=$1
    carpstate=`ifconfig carp0 | grep carp: | awk '{ print $2 }'`
    resources="data"
    delay=3
    
    case "$1" in
    up)
            ifconfig carp0 vhid 1 advskew 10
            for i in ${resources}; do hastctl role primary $i; sleep ${delay}; done
    
            for i in ${resources}; do
                            for n in $( jot 60 ); do
                                    if [ -c "/dev/hast/${i}" ] && break; then
                                            sleep 0.5
                                    fi
    
                                    if [ ! -c "/dev/hast/${i}" ]; then
                                            sleep 1
                                    fi
                            done
            done
    
            for i in ${resources}; do
                    fsck -y -t ufs /dev/hast/$i
                    sleep 5
            done
    
            for i in ${resources}; do
                    mount -t ufs /dev/hast/$i /$i
            done
    ;;
    
    down)
    
    #       ifconfig carp0 vhid 1 advskew 200
            for i in ${resources}; do umount /$i; sleep $delay ; done
            for i in ${resources}; do hastctl role secondary $i; sleep $delay; done
    ;;
    
    boot)
            ifconfig carp0 create
            ifconfig carp0 vhid 1 advskew 200 pass p@ssw0rd 192.168.12.220 255.255.255.0
            sleep 10
            if [ "${carpstate}" = "MASTER" ]; then
                    /sbin/hastd
                    for i in ${resources}; do
                            hastctl role primary $i; sleep ${delay}; done
                                    for n in $( jot 60 ); do
                                            if [ -c "/dev/hast/${i}" ] && break; then
                                                    sleep 0.5
                                            fi
    
                                            if [ ! -c "/dev/hast/${i}" ]; then
                                                    sleep 0.5
                                            fi
                                    done
                    for i in ${resources}; do
                            fsck -y -t ufs /dev/hast/$i
                    done
                    for i in ${resources}; do
                            mount -t ufs /dev/hast/$i /$i
                    done
                    ifconfig carp0 advskew 10
            else
                    /sbin/hastd
                    for i in ${resources}; do hastctl role secondary $i; sleep ${delay}; done
            fi
    esac
    
    Теперь у вас есть система, которая может жить относительно самостоятельно. Самое важное, что система в состоянии определить кто в данный момент главный. Это очень важно. Надеюсь, труд окажется полезным.

    Пожалуйста, уважайте труд автора, при копировании материалов сохраняйте ссылку на источник!

    Комментарии (0)



    Добавление комментариев закрыто.