Промежуточное ПО для баз данных — MyCat

база данных
Промежуточное ПО для баз данных — MyCat
  • Промежуточное ПО базы данных
    • Большой набор баз данных с полностью открытым исходным кодом для разработки корпоративных приложений.
    • Расширенная база данных, которая поддерживает транзакции, ACID и может заменить MySQL.
    • База данных корпоративного уровня, которую можно рассматривать как кластер MySQL для замены дорогого кластера Oracle.
    • Новый SQL Server, объединяющий технологию кэширования памяти, технологию NoSQL и большие данные HDFS.
    • Новое поколение продуктов баз данных корпоративного уровня, сочетающих в себе традиционные базы данных и новые распределенные хранилища данных.
    • Новый промежуточный продукт для баз данных
  • что делать
    • Он используется для поддержки массивного хранилища данных, а также подбазы данных и подтаблицы для массивных данных.
    • Поддержка распределенных транзакций в сценарии подбазы данных и подтаблицы
    • Унифицированная интеграция нескольких источников данных
    • В сценариях приложений с высокой степенью параллелизма уменьшите катастрофическую нагрузку запросов на один узел базы данных.
    • Разделение чтения и записи базы данных может быть реализовано через промежуточный уровень базы данных, так что Java-программа может быть отделена от доступа к базе данных.
  • характеристика
    • Разделение чтения и записи данныхimg
    • разделение данныхimg
    • Интеграция нескольких источников данных

Обзор начала работы с Mycat

что

Mycat — промежуточное ПО для баз данных

  • Промежуточное ПО базы данных

    • Промежуточное ПО: тип компьютерного программного обеспечения, которое соединяет программные компоненты и приложения для облегчения связи между программными компонентами.

      Например: Tomcat, веб-промежуточное ПО.

    • Промежуточное ПО для базы данных: подключение Java-приложения и базы данных

  • Сравнение промежуточного программного обеспечения базы данных

Промежуточное ПО базы данных иллюстрировать
Cobar Cobar принадлежит бизнес-группе Alibaba B2B. Она начала работу в 2008 г. и работает в Alibaba более 3 лет. Она приняла схему из более чем 3000 баз данных MySQL, а кластер обрабатывает более 5 миллиардов онлайн-запросов SQL в день. Cobar прекращает техническое обслуживание в связи с уходом промоутера Cobar
Mycat Mycat — это вторичная разработка open source сообщества на базе кобара Alibaba, которая решает проблемы кобара и добавляет множество новых функций.
OneProxy OneProxy разработан с использованием C на основе официальной идеи прокси MySQL.OneProxy является промежуточным программным обеспечением за коммерческую плату. Отброшены некоторые функции, чтобы сосредоточиться на производительности и стабильности.
kingshard Kingshard разрабатывается небольшой командой на языке го, его все еще нужно развивать и постоянно улучшать.
Vitess Vitess используется Youtube в производстве, и его архитектура очень сложна. Не поддерживает собственный протокол MySQL, требует больших затрат на преобразование для использования.
Atlas Атлас переписан командой 360 на основе прокси mysql, функция нуждается в доработке, и она нестабильна при высоком параллелизме
MaxScale MaxScale — это промежуточное программное обеспечение, разработанное mariadb (версия, поддерживаемая первоначальным автором MySQL).
MySQLRoute MySQLRoute — промежуточное ПО, выпущенное официальной компанией Oracle для MySQL.

Зачем использовать MyCat

  • Связь Java и базы данных

  • Высокий параллелизм и большой объем доступа оказывают большую нагрузку на базу данных.

  • Несогласованные данные запроса на чтение и запись

    image-20201123132751226

Официальный сайт Mycat

что делать

разделение чтения-записи

  • image-20201123134119428

разделение данных

  • image-20201123134818857
Вертикальное разделение (подбиблиотека)
Горизонтальный сплит (разделенный стол)
Вертикальное + горизонтальное разделение (подтаблица подбиблиотеки)

Интеграция нескольких источников данных

  • image-20201123134922138

принцип

  • Наиболее важным глаголом в принципе Mycat является **"intercept"**, который перехватывает оператор SQL, отправленный пользователем. Сначала выполняется определенный анализ оператора SQL: например, анализ фрагментации, анализ маршрутизации, чтение и т. д. написать анализ разделения, анализ кеша и т. д., а затем отправить этот SQL в реальную базу данных на бэкэнде, правильно обработать возвращенный результат и, наконец, вернуть его пользователюimage-20201123135857875

    Таким образом, распространение базы данных отделено от кода, и программист не может определить, используется ли Mycat или MySQL в фоновом режиме.

Установка начинается

Установить

скачать

  • Загрузите tar.gz в среде Linux.В этом примере используется версия 1.6.7.1.

  • адрес загрузки Mycat

  • # 解压
    # z:指定gz压缩包
    # x:指明解压操作
    # v:信息展示
    # f:指定要解压的文件
    tar -zxvf Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz 
    

основной файл конфигурации

  • каталог conf

    • schema.xml: определение логических библиотек, таблиц, узлов сегментирования и т. д.

    • rule.xml: определение правил сегментирования

    • server.xml: определение пользовательских и системных переменных, таких как порты и т. д.

      image-20201123144837919

запускать

Измените файл конфигурации server.xml.

  • каталог confserver.xmlфайл, который легко отличить от mysql

    #conf目录
    cd /usr/local/mycat/mycat/conf/
    #修改server.xml
    vim server.xml
    

    Измените корневой пользователь mycat по умолчанию на mycat и различайте корневого пользователя mysql.image-20201124093820840

Измените файл конфигурации schema.xml.

  • Удалить табличную информацию между тегами, оставив только один тег, и только один тег,

    только пара

  • окончательный эффект

    image-20201124133917979

  • Рекомендуется запустить два-три сервиса mysql.

Проверить доступ к базе данных

  • Mycat в качестве промежуточного программного обеспечения базы данных необходимо развернуть на разных компьютерах с базой данных, поэтому проверьте удаленный доступ.

    mysql -uroot -p123456 -h 192.168.1.8 -P 3306
    mysql -uroot -p123456 -h 192.168.83.133 -P 3306
    

Запустить Mycat

  • Чтобы увидеть журнал запуска в первый раз и облегчить поиск проблемы, мы выбираем метод запуска консоли.

    image-20201124094909119

запуск консоли
  • Выполните консоль ./mycat в каталоге mycat/bin.
начать в фоновом режиме
  • ./mycat запускается в каталоге mycat/bin

Авторизоваться

Окно управления фоном входа

  • Этот метод входа используется для управления и обслуживания Mycat.Порт по умолчанию в окне управления — 9066 и IP-адрес, на котором находится служба Mycat.

    mysql -umycat -p -P 9066 -h 192.168.83.133
    

    image-20201124095239248

    • show databases: настроенное логическое имя базы данных

    • show @@help: команда помощи

    • show @@heartbeat: Обнаружение сердцебиения

      image-20201124134202954

окно данных для входа

  • Этот метод входа используется для запроса данных через Mycat Порт окна данных по умолчанию — 8066 и IP-адрес, на котором находится служба Mycat.

    mysql -umycat -p -P 8066 -h 192.168.83.133
    

    image-20201124134620441

Создайте разделение чтения и записи

  • Благодаря репликации мастер-подчиненный Mycat и MySQL установлено разделение базы данных для чтения и записи для реализации высокой доступности MySQL.

Один хозяин и один раб

Архитектура

  • Один ведущий используется для обработки всех запросов на запись, а один подчиненный отвечает за все запросы на чтение.Схема архитектуры выглядит следующим образом.image-20201124135047324

Принцип репликации master-slave MySQL

  • Двоичные файлы журнала копируютсяimage-20201124135214422
    • Разница заключается в репликации redis master-slave.Репликация master-slave MySQL начинается с точки входа в файл журнала, а Redis запускается с нуля.

Взаимный доступ между контейнерами докеров

  • Как несколько контейнеров получают доступ друг к другу?По умолчанию контейнеры могут обращаться друг к другу через IP-адреса, назначенные мостом docker0, но поскольку IP-адрес нельзя зафиксировать, это не удобно для повседневного использования.

    • В самом Docker тоже есть команда link, с помощью которой можно соединить два контейнера, но недостаток этой команды в том, что ее можно соединить только в одну сторону, то есть два контейнера A и B, только A может получить доступ к B или B можно получить доступ к A, а AB нельзя. прямые одновременные визиты

    • Поэтому в целом рекомендуется использоватьСпособ создания новой сети для настройки контейнера, формат команды для создания новой сети:

      docker network create -d bridge newnet
      

      -d означает не запуск в фоновом режиме, а указаниеТип сети, что означает, что новый созданный тип сети является мостом с именем newnet

  • Создать новую сеть

    docker network create --subnet=172.18.1.0/24 newnet
    
    • Просмотрите сеть, вы можете увидеть только что созданную сеть

      docker network ls
      
  • После создания сети, если вам нужно указать контейнер для использования соответствующей сети, вам нужно только добавить--network а также--ipКоманду можно использовать для создания контейнера mysql следующим образом.

    docker run --name mysql3307 --network newnet --ip 172.18.1.37 -p 3307:3306 -v /var/mycatVolume/mysql3307/data:/var/lib/mysql  -v /var/mycatVolume/mysql3307/conf/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.31
    
  • docker inspectИдентификатор контейнера Просмотр информации о сети

    image-20201124162745534

  • Docker запускает несколько служб mysql

    Установите единую коммуникацию, чтобы гарантировать, что контейнеры могут получить доступ друг к другу

    • mysql создайте новую папку и файл конфигурации и создайте новый локальный файл

      mkdir -p /var/mycatVolume/mysql3307/data
      mkdir -p /var/mycatVolume/mysql3307/conf
      #conf目录下创建 my.cnf
      touch my.cnf
      
    • my.cnfСодержание выглядит следующим образом

      [mysqld]
      #主服务器唯一ID
      server-id=1
      #启用二进制日志
      log-bin=mysql-bin
      
  • Создать контейнер mysql 3307, 3308

    #3307
    docker run --name mysql3307  -p 3307:3306 --network newnet --ip 172.18.1.37 -v /var/mycatVolume/mysql3307/data:/var/lib/mysql  -v /var/mycatVolume/mysql3307/conf/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.31
    
    #3308
    docker run --name mysql3308  -p 3308:3306 --network newnet --ip 172.18.1.38 -v /var/mycatVolume/mysql3308/data:/var/lib/mysql  -v /var/mycatVolume/mysql3308/conf/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.31
    

конфигурация ведущий-ведомый

  • Шаг 1: Хост изменяет файл конфигурации/var/mycatVolume/mysql3307/confПод содержаниемmy.cnf

    [mysqld]
    #主服务器唯一ID
    server-id=17
    #启用二进制日志
    log-bin=mysql-bin
    #设置不需要复制的数据库(可设置多个)
    #binlog-ignore-db=mysql
    #binlog-ignore-db=information_schema
    #设置需要复制的数据库
    binlog-do-db=ms03
    
  • Шаг 2: Измените файл конфигурации с машины/var/mycatVolume/mysql3308/confПод содержаниемmy.cnf

    [mysqld]
    #服务器唯一ID
    server-id=18
    #启用中继日志
    relay-log=mysql-relay
    
  • Шаг 3: Изменитьmy.cnfПосле настройки службу MySQL необходимо перезапустить

  • Шаг 4: Создайте учетную запись на хосте и авторизуйте подчиненный

    GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY '123123';
    
    • Запрос состояния мастера

      show master status;
      

      Запишите значения File и Position; после этого шага не используйте главный сервер MySQL, чтобы предотвратить изменение значения состояния главного сервера.image-20201125173242029

  • Шаг 5: Настройте хост, который необходимо реплицировать на ведомом устройстве.

    #复制主机的命令
    CHANGE MASTER TO MASTER_HOST='172.18.1.37',
    MASTER_USER='slave',
    MASTER_PASSWORD='123123',
    MASTER_LOG_FILE='mysql-bin.000010',
    MASTER_LOG_POS=154,
    master_port=3306;
    
    • Запустите функцию ведомого копирования

      start slave;
      
    • Остановить функцию ведомого копирования

      start slave;
      
    • сбросить конфигурацию ведомого

      stop slave;
      reset slave;
      
    • Посмотреть статус ведомого

      show slave status\G;
      

      image-20201125173748532

  • Шаг 6. Убедитесь, что репликация ведущий-ведомый действительна.

    • Вставить данные в пользовательскую таблицу в ms03

      image-20201125174640792

      image-20201125174724887

Mycat реализует разделение чтения и записи

  • Шаг 1: Подготовкаvim mycat/confв каталогеschema.xml, Просмотр конфигурации разделения чтения-записи Mycat

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://io.mycat/">
    
            <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
            </schema>
            <dataNode name="dn1" dataHost="host1" database="ms03" />
            <dataHost name="host1" maxCon="1000" minCon="10" balance="0"
                              writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                    <heartbeat>select user()</heartbeat>
                    <!-- can have multi write hosts -->
                    <writeHost host="hostM1" url="192.168.83.133:3307" user="root"
                                       password="123456">
                            <!-- can have multi read hosts -->
                            <readHost host="hostS1" url="192.168.83.133:3308" user="root" password="123456" />
                    </writeHost>
                    </dataHost>
    </mycat:schema>
    
    • 3307 Хост создает/выбирает базу данных ms03 и создает новую таблицу mytbl
    use ms03;
    create table mytbl(id int,name varchar(20));
    insert into mytbl values(1,'z3');
    select * from mytbl;
    
    • Ведомый запрос, успешно ли выполнена репликация
  • Шаг 2: Запустите службу Mycat

    image-20201126101702136

  • Третий шаг: авторизуйтесь в окне данных Mycat 8066

    mysql -umycat -h 192.168.83.133 -P 8066 -p
    

    image-20201126102225218

  • Шаг 4. Убедитесь, что разделение чтения и записи

    • Вставленный в ведомый, цель состоит в том, чтобы сделать данные ведущий-ведомый несогласованными

      insert into mytbl values (4,'only');
      

      image-20201126105048323

      Можно видеть, что операция записи хоста и функция операции чтения подчиненного устройства в настоящее время не реализованы.

    • Измените файл конфигурации Mycat,vim mycat/confв каталогеschema.xml, измененоbalanceсвойство, настроенное через это свойствоТипы разделения чтения-записи

      Тип балансировки нагрузки, в настоящее время существует 4 значения:

      • Первый тип: balance="0", механизм разделения чтения-записи не включен, и все операции чтения отправляются на доступный в данный момент writeHost
      • Второй тип: balance="1", все readHost и резервные writeHost участвуют в балансировке нагрузки оператора select. Проще говоря, когда режим двойного ведущего и двойного ведомого (M1->S1, M2->S2, и M1 и M2 взаимодействуют друг с другом) Активный и резервный), при нормальных обстоятельствах M2, S1 и S2 участвуют в балансировке нагрузки оператора select.
      • Третий тип: balance="2", все операции чтения распределяются случайным образом на writeHost и readHost
      • Четвертый тип: balance="3", все запросы на чтение случайным образом распределяются на readhost для выполнения, writeHost не выдерживает давления чтения
    • будетschema.xmlИзмените атрибут баланса на 2 и перезапустите сервер Mycat.

      Вы можете видеть, что запросы на чтение случайным образом распределяются между главной и подчиненной машинами.

      image-20201126111537494

Двойной ведущий и двойной ведомый

  • Ведущее устройство m1 обрабатывает все запросы на запись, его ведомое устройство s1 и еще одно ведущее устройство m2 и его ведомое устройство s2 отвечают за все запросы на чтение. Когда m1 не работает, хост m2 отвечает за запись запросов, а m1 и m2 являются резервными машинами друг для друга. Схема архитектуры выглядит следующим образом:image-20201126112139908

    • сочинение

      3307 и 3317 как двойной хост

      3308 и 3318 как двойные ведомые

Конфигурация с двумя хостами

  • Конфигурация 3307 Master1

    #主服务器唯一ID
    server-id=7
    #启用二进制日志
    log-bin=mysql-bin
    #设置不需要复制的数据库(可设置多个)
    binlog-ignore-db=mysql
    binlog-ignore-db=information_schema
    #设置需要复制的数据库
    binlog-do-db=ms03
    #设置logbin格式
    binlog_format=STATEMENT
    #在作为从数据库的时候,有写入操作也要更新二进制日志文件
    log-slave-updates
    #表示自增长字段每次递增的量,指自增长字段的起始值,其默认值是1,取值范围是1 ...65535
    auto-increment-increment=2
    #表示自增长字段从那个数开始,指字段一次递增多少,它的取值范围是1...65535
    auto-increment-offset=1
    
  • 3317 Конфигурация Master2

    #主服务器唯一ID
    server-id=17
    #启用二进制日志
    log-bin=mysql-bin
    #设置不需要复制的数据库(可设置多个)
    binlog-ignore-db=mysql
    binlog-ignore-db=information_schema
    #设置需要复制的数据库
    binlog-do-db=ms03
    #设置logbin格式
    binlog_format=STATEMENT
    #在作为从数据库的时候,有写入操作也要更新二进制日志文件
    log-slave-updates
    #表示自增长字段每次递增的量,指自增长字段的起始值,其默认值是1,取值范围是1 ...65535
    auto-increment-increment=2
    #表示自增长字段从那个数开始,指字段一次递增多少,它的取值范围是1...65535
    auto-increment-offset=2
    

Двойная ведомая конфигурация

  • 3308

    [mysqld]
    #服务器唯一ID
    server-id=8
    #启用中继日志
    relay-log=mysql-relay
    
  • 3318

    [mysqld]
    #服务器唯一ID
    server-id=18
    #启用中继日志
    relay-log=mysql-relay
    

Запустите четыре контейнера mysql

docker run --name mysql3307  -p 3307:3306 --network newnet --ip 172.18.1.7 -v /var/mycatVolume/mysql3307/data:/var/lib/mysql  -v /var/mycatVolume/mysql3307/conf/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.31
docker run --name mysql3308  -p 3308:3306 --network newnet --ip 172.18.1.8 -v /var/mycatVolume/mysql3308/data:/var/lib/mysql  -v /var/mycatVolume/mysql3308/conf/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.31
docker run --name mysql3317  -p 3317:3306 --network newnet --ip 172.18.1.17 -v /var/mycatVolume/mysql3317/data:/var/lib/mysql  -v /var/mycatVolume/mysql3317/conf/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.31
docker run --name mysql3318  -p 3318:3306 --network newnet --ip 172.18.1.18 -v /var/mycatVolume/mysql3318/data:/var/lib/mysql  -v /var/mycatVolume/mysql3318/conf/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.31
  • Создайте учетную запись на обоих хостах и ​​авторизуйте подчиненный

    #在主机MySQL里执行授权命令
    GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY '123123';
    #查询Master1的状态
    show master status;
    
    #分别记录下File和Position的值
    #执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化
    
    • Master1

      image-20201126133755900

    • Master2

      image-20201126133914710

  • Настройте хост, который необходимо реплицировать на ведомом устройстве.

    #复制主机的命令
    CHANGE MASTER TO MASTER_HOST='主机的IP地址',
    MASTER_USER='slave',
    MASTER_PASSWORD='123123',
    MASTER_LOG_FILE='mysql-bin.具体数字',MASTER_LOG_POS=具体值;
    
    • Команда копирования для Slave1

      #复制主机1的命令
      CHANGE MASTER TO MASTER_HOST='172.18.1.7',
      MASTER_USER='slave',
      MASTER_PASSWORD='123123',
      MASTER_LOG_FILE='mysql-bin.000014',
      MASTER_LOG_POS=443,
      master_port=3306;
      
    • Команда копирования Slave2

      #复制主机2的命令
      CHANGE MASTER TO MASTER_HOST='172.18.1.17',
      MASTER_USER='slave',
      MASTER_PASSWORD='123123',
      MASTER_LOG_FILE='mysql-bin.000003',
      MASTER_LOG_POS=732,
      master_port=3306;
      
    • Запустите функцию подчиненной репликации и просмотрите состояние подчиненной службы.

      #启动两台从服务器复制功能
      start slave;
      #查看从服务器状态
      show slave status\G;
      

      Следующие два параметра - Да, это означает, что конфигурация ведущий-ведомый прошла успешно!Slave_IO_Running: Yes ,Slave_SQL_Running: Yes

      image-20201126134707412

      image-20201126134731683

Два хоста копируют друг друга

  • Мастер2 копирует Мастер1, Мастер1 копирует Мастер2

    #Master2
    CHANGE MASTER TO MASTER_HOST='172.18.1.7',
    MASTER_USER='slave',
    MASTER_PASSWORD='123123',
    MASTER_LOG_FILE='mysql-bin.000014',
    MASTER_LOG_POS=443,
    master_port=3306;
    
    #Master1
    CHANGE MASTER TO MASTER_HOST='172.18.1.17',
    MASTER_USER='slave',
    MASTER_PASSWORD='123123',
    MASTER_LOG_FILE='mysql-bin.000003',
    MASTER_LOG_POS=732,
    master_port=3306;
    
    
    
    #启动两台主服务器复制功能
    start slave;
    #查看从服务器状态
    show slave status\G;
    

    image-20201126135346242

    image-20201126135409317

Проверка двойного ведущего и двойного ведомого

  • Мастер1 хост новая библиотека, новая таблица, вставка записи, Мастер2 и подчиненная репликация

    create table doublems(id int,name varchar(50));
    insert into doublems values(1,'touchair');
    

    image-20201126150448777

Изменить файл конфигурации Mycat

  • ИзмененоbalanceСвойство, настроить тип чтения и записи через это свойство

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://io.mycat/">
    
            <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
            </schema>
            <dataNode name="dn1" dataHost="host1" database="ms03" />
            <dataHost name="host1" maxCon="1000" minCon="10" balance="1"
                              writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                    <heartbeat>select user()</heartbeat>
                    <!-- can have multi write hosts -->
                    <writeHost host="hostM1" url="192.168.83.133:3307" user="root"
                                       password="123456">
                            <!-- can have multi read hosts -->
                            <readHost host="hostS1" url="192.168.83.133:3308" user="root" password="123456" />
                    </writeHost>
                 <writeHost host="hostM2" url="192.168.83.133:3317" user="root"
                                       password="123456">
                            <!-- can have multi read hosts -->
                            <readHost host="hostS2" url="192.168.83.133:3318" user="root" password="123456" />
                    </writeHost>
                    </dataHost>
    </mycat:schema>
    
    • balance="1": Все readHost и резервные writeHost участвуют в балансировке нагрузки оператора select.
    • writeType="0": Все операции записи отправляются на первый настроенный writeHost, первый зависает, а второй еще жив
    • writeType="1", все операции записи случайным образом отправляются на настроенный writeHost, не рекомендуется после 1.5
    • writeHost, после перезагрузки подлежит переключению, переключение записывается в конфигурационный файл: dnindex.properties
    • switchType="1": 1 значение по умолчанию, автоматическое переключение, -1 означает отсутствие автоматического переключения, 2 на основе состояния синхронизации master-slave MySQL, чтобы решить, переключаться или нет

    image-20201126151245712

Проверить разделение чтения и записи

  • Вставьте данные с системными переменными в таблицу базы данных doublems Master1 на хосте записи, что приведет к несогласованности данных master-slave.

    INSERT INTO doublems  VALUES(2,@@server_id);
    

    image-20201126152011445

  • Запустите Mycat и проверьте разделение чтения и записи в окне данных Mycat.

    image-20201126152339123

Способность к защите от рисков

  • После остановки Master1 попробуйте вставить данные в Mycat

    Данные по-прежнему можно вставлять в Mycat, Master2 автоматически переключается на хост, а Slave1 и Slave2 копируют операции чтения

    image-20201126152802495

  • Перезапустите Master1 в это время

    image-20201126152946281

  • Master1 и Master2 действуют как резервные машины друг для друга, хост, отвечающий за запись, отключен, а резервная машина отвечает за операции записи, чтобы обеспечить высокую доступность разделения базы данных для чтения и записи.

Вертикальное разделение - подбиблиотека

  • База данных состоит из множества таблиц, каждая из которых соответствует определенному бизнесу. Вертикальная сегментация означает классификацию таблиц в соответствии с бизнесом и распределение их по разным базам данных, таким образом разделяя данные или оказывая давление на разные базы данных. Как показано ниже:image-20201127112702144

    Система разделена на несколько модулей: пользовательский, транзакционный и платежный.

Как разделить стол

  • Один вопрос: Могут ли таблицы в двух базах данных на двух хостах быть связаны с запросом?

    Ответ: нет

принцип деления

  • Принцип подбиблиотеки: таблицы с близкой связью должны быть в одной библиотеке, а таблицы не связанные друг с другом можно разбить на разные библиотеки

    • #在Mycat中执行
      #客户表 rows:20万
      CREATE TABLE customer(
       id INT AUTO_INCREMENT,
       NAME VARCHAR(200),
       PRIMARY KEY(id)
      );
      
      #订单表 rows:600万
      CREATE TABLE orders(
       id INT AUTO_INCREMENT,
       order_type INT,
       customer_id INT,
       amount DECIMAL(10,2),
       PRIMARY KEY(id)
       );
       
       #订单详细表 rows:600万
      CREATE TABLE orders_detail(
       id INT AUTO_INCREMENT,
       detail VARCHAR(2000),
       order_id INT,
       PRIMARY KEY(id)
      );
      #订单状态字典表 rows:20
      CREATE TABLE dict_order_type(
       id INT AUTO_INCREMENT,
       order_type VARCHAR(200),
       PRIMARY KEY(id)
      );
      
    • Как разделить приведенные выше четыре таблицы на базу данных?

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

      image-20201127113945325

      Нам нужно только подключиться к промежуточному программному обеспечению базы данных Mycat, а затем Mycat для доступа к различным базам данных.

Mycat реализует принцип подбиблиотеки

  • Ядро Mycat:Перехват SQL——Семантический анализ SQL———Вперед

Реализовать подбиблиотеки

  • Изменить файл конфигурации Mycat

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://io.mycat/">
    
            <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
                <table name="customer" dataNode="dn2" ></table>
            </schema>
            <dataNode name="dn1" dataHost="host1" database="orders" />
        	<dataNode name="dn2" dataHost="host2" database="orders" />
            <dataHost name="host1" maxCon="1000" minCon="10" balance="0"
                              writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                    <heartbeat>select user()</heartbeat>
                    <!-- can have multi write hosts -->
                    <writeHost host="hostM1" url="192.168.83.133:3327" user="root"
                                       password="123456">
                    </writeHost>
                    </dataHost>
         <dataHost name="host2" maxCon="1000" minCon="10" balance="0"
                              writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                    <heartbeat>select user()</heartbeat>
                    <!-- can have multi write hosts -->
                    <writeHost host="hostM2" url="192.168.83.133:3328" user="root"
                                       password="123456">
                    </writeHost>
                    </dataHost>
    </mycat:schema>
    

    customerпоходка за столомdn2В базе данных 3328 узлов, остальные пропали.dn1База данных 3327 узловimage-20201130105614077

  • Запустите службу Mysql 3327,3328 и создайте два новых пустых заказа базы данных.

    #3327
    docker run --name mysql3327  -p 3327:3306 --network newnet --ip 172.18.1.27 -v /var/mycatVolume/mysql3327/data:/var/lib/mysql  -v /var/mycatVolume/mysql3327/conf/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.31
    
    #3328
    docker run --name mysql3328  -p 3328:3306 --network newnet --ip 172.18.1.28 -v /var/mycatVolume/mysql3328/data:/var/lib/mysql  -v /var/mycatVolume/mysql3328/conf/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7.31
    
    #创建数据库orders
    create database orders;
    
  • Выполните оператор создания таблицы в Mycat

    #在Mycat中执行
    #客户表 rows:20万
    CREATE TABLE customer(
     id INT AUTO_INCREMENT,
     NAME VARCHAR(200),
     PRIMARY KEY(id)
    );
    
    #订单表 rows:600万
    CREATE TABLE orders(
     id INT AUTO_INCREMENT,
     order_type INT,
     customer_id INT,
     amount DECIMAL(10,2),
     PRIMARY KEY(id)
     );
     
     #订单详细表 rows:600万
    CREATE TABLE orders_detail(
     id INT AUTO_INCREMENT,
     detail VARCHAR(2000),
     order_id INT,
     PRIMARY KEY(id)
    );
    #订单状态字典表 rows:20
    CREATE TABLE dict_order_type(
     id INT AUTO_INCREMENT,
     order_type VARCHAR(200),
     PRIMARY KEY(id)
    );
    
    • Посетите Mycat:mysql -umycat -p123456 -h 192.168.83.133 -P 8066Переключиться на TESTDB, создать 4 таблицы

      Просмотрите информацию о таблице, вы можете увидеть успешную подбазу данных

      image-20201130105320011

      image-20201130105415846

      image-20201130105510285

Горизонтальное разделение — подтаблица

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

    image-20201130110526618

Реализовать подтаблицы

Выберите таблицу для разделения

  • Существует узкое место в количестве данных, хранимых в одной таблице в MySQL.Узкое место достигается, когда выражено всего 10 миллионов фрагментов данных, что повлияет на эффективность запроса.Для оптимизации необходимо разбить его по горизонтали (таблицы).
  • Например: заказы и сведения о заказе достигли 6 миллионов строк данных, и их необходимо оптимизировать для подтаблиц.

Поля подтаблицы

  • Взяв в качестве примера таблицу заказов, таблицу можно разделить по разным полям.

    Поля подтаблицы Эффект
    id (первичный ключ или время создания) Заказы запросов обращают внимание на своевременность, а исторические заказы запрашиваются реже.Такая фрагментация приведет к тому, что один узел будет посещать больше, а один - меньше, что неравномерно.
    customer_id Согласно идентификатору клиента, два узла имеют средний доступ, и все заказы клиента находятся на одном узле.

Измените файл конфигурации schema.xml.

  • Установите узлы данных как dn1 и dn2 для таблицы заказов и укажите правило сегментирования какtouchair_rule(пользовательское имя)

    <table name="orders" dataNode="dn1,dn2" rule="touchair_rule" ></table>
    

    image-20201130135915135

Измените файл конфигурации rule.xml.

  • существуетruleДобавьте правила шардинга в файл конфигурацииtouchair_role, и укажите применимое правило как полеcustomer_id, и выбор алгоритма шардингаmod-long(операция по модулю над полями),customer_idВычислить по модулю двух узлов, шардировать по результату и настроить алгоритмmod-longпараметрcount2, два узла

    <tableRule name="touchair_rule">
     <rule>
     <columns>customer_id</columns>
     <algorithm>mod-long</algorithm>
     </rule>
     </tableRule>
    
    <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
     <!-- how many data nodes -->
     <property name="count">2</property>
     </function>
    

    image-20201130141112654

    image-20201130141152133

  • После завершения настройки на узле базы данных dn2 3328 создайтеordersповерхность

    image-20201130141732131

Перезапустите Mycat, чтобы конфигурация вступила в силу.

Доступ к Mycat для сегментирования

  • Вставить данные в таблицу заказов в Mycat,Поля INSERT не могут быть опущены

    INSERT INTO orders(id,order_type,customer_id,amount) VALUES (1,101,100,100100);
    INSERT INTO orders(id,order_type,customer_id,amount) VALUES(2,101,100,100300);
    INSERT INTO orders(id,order_type,customer_id,amount) VALUES(3,101,101,120000);
    INSERT INTO orders(id,order_type,customer_id,amount) VALUES(4,101,101,103000);
    INSERT INTO orders(id,order_type,customer_id,amount) VALUES(5,102,101,100400);
    INSERT INTO orders(id,order_type,customer_id,amount) VALUES(6,102,100,100020);
    

    image-20201130143818561

Осколок Mycat "присоединиться"

  • Таблица заказов Orders была разделена на таблицы Как выполнить запрос соединения к связанной с ней таблице деталей Orders_detail

    • Также нам необходимо выполнить операции шардинга на orders_detail, принцип Join следующий:

      image-20201130144416208

Таблица ER

  • Mycat опирается на дизайнерские идеи Foundation DB, новичка в области NewSQL. Foundation DB новаторски предлагает концепцию группы таблиц, которая зависит от места хранения подтаблиц в основной таблице и физически примыкает к ним, таким образом полное решение эффективности JOIN В соответствии с этой идеей предлагается стратегия сегментирования базы данных, основанная на отношениях ER.Записи дочерней таблицы и связанные записи родительской таблицы хранятся в одном и том же сегменте данных.

Измените файл конфигурации schema.xml.

  • Добавить элементы конфигурации

    <childTable name="orders_detail" primaryKey="id" joinKey="order_id" parentKey="id" />
    

    image-20201130151019264

  • Создано на дн2orders_detailповерхность

     #订单详细表
    CREATE TABLE orders_detail(
     id INT AUTO_INCREMENT,
     detail VARCHAR(2000),
     order_id INT,
     PRIMARY KEY(id)
    );
    

    image-20201130151348662

Перезапустите Mycat, чтобы конфигурация вступила в силу.

Доступ к Mycat для вставки данных в таблицу orders_detail

  • вставить данные

    INSERT INTO orders_detail(id,detail,order_id) values(1,'detail1',1);
    INSERT INTO orders_detail(id,detail,order_id) VALUES(2,'detail1',2);
    INSERT INTO orders_detail(id,detail,order_id) VALUES(3,'detail1',3);
    INSERT INTO orders_detail(id,detail,order_id) VALUES(4,'detail1',4);
    INSERT INTO orders_detail(id,detail,order_id) VALUES(5,'detail1',5);
    INSERT INTO orders_detail(id,detail,order_id) VALUES(6,'detail1',6);
    

Запустите два оператора соединения таблиц в mycat, dn1, dn2.

  • Select o.*,od.detail from orders o inner join orders_detail od on o.id=od.order_id;
    
  • Запуск связанных операторов в Mycat

    image-20201130152021923

  • выполнить оператор соединения в dn1 3327

    image-20201130152201811

  • выполнить оператор соединения в dn2 3328

    image-20201130152241234

глобальная таблица

  • В случае сегментирования, когда бизнес-таблица сегментируется из-за масштаба, связь между бизнес-таблицей и этими дочерними таблицами словаря становится более сложной проблемой, учитывая, что таблица словаря имеет следующие характеристики:

    • 1: Изменения не частые
    • 2: Общий объем данных не сильно изменился
    • 3: Размер данных небольшой, редко превышает сотни тысяч записей.

    Ввиду этого Mycat определяет специальную таблицу, называемую «глобальной таблицей». Глобальная таблица имеет следующие характеристики:

    ① Операции вставки и обновления глобальной таблицы будут выполняться на всех узлах в режиме реального времени для обеспечения согласованности данных каждого сегмента.

    ② Операция запроса глобальной таблицы выполняется только с одного узла.

    ③ Глобальная таблица может выполнять операцию JOIN с любой таблицей.

    Определение таблиц словаря или некоторых таблиц, которые соответствуют характеристикам таблиц словаря, как глобальных таблиц, с другой стороны, очень хорошо решает проблему объединения данных.Благодаря стратегии фрагментации глобальной таблицы + отношения E-R Mycat может удовлетворить более 80% корпоративных приложений. разработка

Измените файл конфигурации schema.xml.

  • Добавить элементы конфигурации

    <table name="dict_order_type" dataNode="dn1,dn2" type="global" ></table>
    

    image-20201130164700921

Перезапустите Mycat, чтобы конфигурация вступила в силу.

Создайте таблицу dict_order_type в dn2

  • построить таблицу

    CREATE TABLE dict_order_type(
     id INT AUTO_INCREMENT,
     order_type VARCHAR(200),
     PRIMARY KEY(id)
    );
    

    image-20201130164938054

Доступ к Mycat для вставки данных в таблицу dict_order_type

INSERT INTO dict_order_type(id,order_type) VALUES(101,'type1');
INSERT INTO dict_order_type(id,order_type) VALUES(102,'type2');

Данные таблицы запроса в Mycat, dn1, dn2

  • Mycat

    image-20201130165212255

  • dn1 3327

    image-20201130165317710

  • dn2 3328

    image-20201130165343107

Общие правила шардинга

по модулю

  • Это правило является операцией по модулю над полем осколка. Это также наиболее часто используемое правило для подтаблиц уровней. 5.1 В подтаблице конфигурации таблица заказов использует это правило.

Перечисление осколков

  • Настроив возможные идентификаторы перечисления в файле конфигурации, вы можете настроить сегментирование самостоятельно. Это правило применимо к конкретным сценариям. Например, некоторые предприятия необходимо сохранить по провинциям или районам и округам. Используйте это правило.
Измените файл schema.xml
<table name="orders_ware_info" dataNode="dn1,dn2" rule="sharding_by_intfile" ></table>

image-20201130171159812

Изменить правило.xml
<tableRule name="sharding_by_intfile">
 <rule>
 <columns>areacode</columns>
 <algorithm>hash-int</algorithm>
 </rule>
 </tableRule>


<function name="hash-int"
 class="io.mycat.route.function.PartitionByFileMap">
 <property name="mapFile">partition-hash-int.txt</property>
 <property name="type">1</property>
 <property name="defaultNode">0</property>
 </function>


# columns:分片字段,algorithm:分片函数
# mapFile:标识配置文件名称,type:0为int型、非0为String, #defaultNode:默认节点:小于 0 表示不设置默认节点,大于等于 0 表示设置默认节点, # 设置默认节点如果碰到不识别的枚举值,就让它路由到默认节点,如不设置不识别就报错

image-20201130172717255

image-20201130172807884

Измените файл конфигурации partition-hash-int.txt.
110=0
120=1
Перезапустите Mycat
Посетите Mycat, чтобы создать информационный лист области атрибуции заказа.
  • создать таблицу

    CREATE TABLE orders_ware_info
    (
     `id` INT AUTO_INCREMENT comment '编号',
     `order_id` INT comment '订单编号',
     `address` VARCHAR(200) comment '地址',
    `areacode` VARCHAR(20) comment '区域编号',
    PRIMARY KEY(id)
    );
    
вставить данные
INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (1,1,'bj','110');
INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (2,2,'sz','120');
INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (3,3,'dy','120');
INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (4,4,'cz','110');
INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (5,5,'wx','110');
INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (6,6,'sh','120');
Запросите Mycat, dn1, dn2, чтобы увидеть эффект фрагментации данных.
  • Mycat

    image-20201201083609359

  • dn1 3327

    image-20201201083652974

  • dn2 3328

    image-20201201083724841

соглашение о сфере применения

  • Этот сегмент подходит для предварительного планирования того, к какому сегменту относится ряд полей сегмента.
Измените файл schema.xml
  • Добавить элементы конфигурации

    <table name="payment_info" dataNode="dn1,dn2" rule="auto_sharding_long" ></table>
    

    image-20201201090006888

Измените файл rule.xml
  • добавить правило

    <tableRule name="auto_sharding_long">
       <rule>
         <columns>order_id</columns>
         <algorithm>rang-long</algorithm>
       </rule>
    </tableRule>
    

    image-20201201090614232

  • Конфигурация алгоритма

     <function name="rang-long"
               	class="io.mycat.route.function.AutoPartitionByLong">
             	<property name="mapFile">autopartition-long.txt</property>
         		<property name="defaultNode">0</property>
    </function>
    
    

    столбцы: поле фрагментации, алгоритм: функция фрагментации

    mapFile: определяет имя файла конфигурации

    defaultNode: узел по умолчанию: меньше 0 означает отсутствие установки узла по умолчанию, больше или равно 0 означает установку узла по умолчанию, если узел по умолчанию встречает нераспознанное значение перечисления, он будет перенаправлен на узел по умолчанию, если это не так. установить, он сообщит об ошибке

  • Исправлятьautopartition-long.txtдокумент

    0-102=0
    103-200=1
    
Перезапустите Mycat
Получите доступ к Mycat и создайте таблицу
  • Создать таблицу SQL

    #支付信息表
    CREATE TABLE payment_info
    (
     `id` INT AUTO_INCREMENT comment '编号',
     `order_id` INT comment '订单编号',
     `payment_status` INT comment '支付状态',
     PRIMARY KEY(id)
    );
    
  • вставить данные

    INSERT INTO payment_info (id,order_id,payment_status) VALUES (1,101,0);
    INSERT INTO payment_info (id,order_id,payment_status) VALUES (2,102,1);
    INSERT INTO payment_info (id,order_id ,payment_status) VALUES (3,103,0);
    INSERT INTO payment_info (id,order_id,payment_status) VALUES (4,104,1);
    
Запросите Mycat, dn1, dn2, чтобы увидеть эффект фрагментации данных.
  • Mycat

    image-20201201092100956

  • dn1

    image-20201201092135953

  • dn2

    image-20201201092158976

Осколок по дате (день)

  • Это правило разделено по дням, а также заданы формат времени и диапазон.
Измените файл schema.xml
  • Добавить файл конфигурации

    <table name="login_info" dataNode="dn1,dn2" rule="sharding_by_date" ></table>
    
Изменить правило.xml
  • Изменить правила

    <tableRule name="sharding_by_date">
        <rule>
            <columns>login_date</columns>
            <algorithm>shardingByDate</algorithm>
        </rule>
    </tableRule>
    

    image-20201201093756784

  • Конфигурация алгоритма

    <function name="shardingByDate" class="io.mycat.route.function.PartitionByDate">
        <property name="dateFormat">yyyy-MM-dd</property>
        <property name="sBeginDate">2019-01-01</property>
        <property name="sEndDate">2019-01-04</property>
        <property name="sPartionDay">2</property> 
    </function>
    
    
    # columns:分片字段,algorithm:分片函数
    #dateFormat :日期格式
    #sBeginDate :开始日期
    #sEndDate:结束日期,则代表数据达到了这个日期的分片后循环从开始分片插入
    #sPartionDay :分区天数,即默认从开始日期算起,分隔 2 天一个分区
    

    image-20201201093722602

Перезапустите Mycat
Доступ к Mycat для создания таблицы
  • Создать таблицу SQL

    #用户信息表
    CREATE TABLE login_info
    (
     `id` INT AUTO_INCREMENT comment '编号',
     `user_id` INT comment '用户编号',
     `login_date` date comment '登录日期',
     PRIMARY KEY(id)
    );
    
вставить данные
  • Вставить SQL

    INSERT INTO login_info(id,user_id,login_date) VALUES (1,101,'2019-01-01');
    INSERT INTO login_info(id,user_id,login_date) VALUES (2,102,'2019-01-02');
    INSERT INTO login_info(id,user_id,login_date) VALUES (3,103,'2019-01-03');
    INSERT INTO login_info(id,user_id,login_date) VALUES (4,104,'2019-01-04');
    INSERT INTO login_info(id,user_id,login_date) VALUES (5,103,'2019-01-05');
    INSERT INTO login_info(id,user_id,login_date) VALUES (6,104,'2019-01-06');
    
Запросите Mycat, dn1, dn2, чтобы увидеть эффект фрагментации данных.
  • Mycat

    image-20201201094158708

  • dn1

    image-20201201094302388

  • dn2

    image-20201201094320496

глобальная последовательность

  • В приведенном выше примере идентификатор жестко закодирован и вставлен, но реальная сцена неприменима, так как же предотвратить повторение идентификатора и конфликты?
  • В случае реализации подбазы данных и подтаблицы база данныхСамоувеличивающийся первичный ключ больше не может гарантировать глобальную уникальность самоувеличивающегося первичного ключа.. Для этого Mycat предоставляетглобальная последовательность, и предоставляет различные методы реализации, включая локальную настройку и настройку базы данных.

метод локального файла

  • Таким образом, Mycat настраивает последовательность в файл.Когда конфигурация в последовательности используется, Mycat обновит текущее значение файла sequence_conf.properties в пути к классам.
    • Преимущества: локальная загрузка, более высокая скорость чтения
    • Недостатки: слабая защита от рисков, после того, как хост, на котором Mycat не работает, не может читать локальные файлы.

Метод базы данных (рекомендуется)

  • Таблица в БД используется для подсчета и накопления, но нет необходимости читать и записывать БД каждый раз при генерации последовательности, что слишком неэффективно. Mycat предварительно загрузит часть числового сегмента в память Mycat, чтобы большая часть последовательностей чтения и записи выполнялась в памяти. Если числовой сегмент в памяти закончится, Mycat один раз запросит базу данных

  • В: Если Mycat выйдет из строя, не пропадет ли последовательность в памяти?

    да. Если это так, Mycat будет обращаться к базе данных за новым сегментом номера после запуска, а исходный сегмент номера будет отброшен.

    То есть при перезапуске Mycat теряется неиспользованный номер текущего сегмента номера, но из-за этого не будет дублирования первичного ключа.

Шаг 1: Создайте скрипт последовательности библиотеки
  • Создать глобальный список последовательностей на dn1

    CREATE TABLE MYCAT_SEQUENCE (NAME VARCHAR(50) NOT NULL,current_value INT NOT
    NULL,increment INT NOT NULL DEFAULT 100, PRIMARY KEY(NAME)) ENGINE=INNODB;
    
  • Функции, необходимые для создания глобальной последовательности

    #开发人员无需考虑 以下语句怎么写
    #遵循官方文档
    DELIMITER $$ 
    CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) RETURNS VARCHAR(64)
    DETERMINISTIC 
    BEGIN
    DECLARE retval VARCHAR(64);
    SET retval="-999999999,null";
    SELECT CONCAT(CAST(current_value AS CHAR),",",CAST(increment AS CHAR)) INTO retval FROM
    MYCAT_SEQUENCE WHERE NAME = seq_name;
    RETURN retval;
    END $$
    DELIMITER ;
    DELIMITER $$
    CREATE FUNCTION mycat_seq_setval(seq_name VARCHAR(50),VALUE INTEGER) RETURNS 
    VARCHAR(64)
    DETERMINISTIC
    BEGIN
    UPDATE MYCAT_SEQUENCE
    SET current_value = VALUE
    WHERE NAME = seq_name;
    RETURN mycat_seq_currval(seq_name);
    END $$
    DELIMITER ;
    DELIMITER $$
    CREATE FUNCTION mycat_seq_nextval(seq_name VARCHAR(50)) RETURNS VARCHAR(64) 
    DETERMINISTIC
    BEGIN
    UPDATE MYCAT_SEQUENCE
    SET current_value = current_value + increment WHERE NAME = seq_name;
    RETURN mycat_seq_currval(seq_name);
    END $$
    DELIMITER ;
    
  • Инициализировать запись таблицы последовательности

    INSERT INTO MYCAT_SEQUENCE(NAME,current_value,increment) VALUES ('ORDERS', 400000,
    100);
    #查看
    select * from MYCAT_SEQUENCE;
    

    image-20201201102742585

Шаг 2: Измените конфигурацию Mycat
  • Изменить sequence_db_conf.properties

    vim sequence_db_conf.properties
    #意思是 ORDERS这个序列在dn1这个节点上,具体dn1节点是哪台机子,请参考schema.xml
    
    
    #修改server.xml
    vim server.xml
    #全局序列类型:0-本地文件,1-数据库方式,2-时间戳方式。此处应该修改成1。
    

    image-20201201103221691

    image-20201201103353867

Перезапустите Mycat
Проверить глобальную последовательность
  • Войдите в Mycat и введите данные

    insert into orders(id,amount,customer_id,order_type) values(next value for 
    MYCATSEQ_ORDERS,1000,101,102);
    

    image-20201201104931525

    image-20201201104858919

Метод метки времени

  • Глобальный идентификатор последовательности = 64-битный двоичный (42 миллисекунды) + 5 (идентификатор машины) + 5 (сервисный код) + 12 (повторяющееся накопление) преобразуется в длинный тип 18-значного десятичного числа, а 12-битное двоичное накопление может быть одновременно выполняется каждую миллисекунду
    • Плюсы: простая конфигурация
    • Недостаток: 18-битный идентификатор слишком длинный.

Генерируйте глобальные последовательности автономно

  • Глобальные последовательности могут генерироваться автономно в проектах Java.
    • Объединение согласно бизнес-логике
    • Вы можете использовать однопоточный атомарный incr Redis для создания последовательностей, но самогенерация должна быть реализована только в коде Java в проекте, или рекомендуется использовать собственную глобальную последовательность Mycat.

Высокая доступность Mycat на основе механизма высокой доступности

  • В реальном проекте служба Mycat также должна учитывать высокую доступность.Если сервер, на котором находится Mycat, не работает или служба Mycat выходит из строя, для предоставления услуг требуется резервная машина, и необходимо учитывать кластер Mycat.

Решение высокой доступности

  • Мы можем использовать HAProxy+KeepAlived с двумя Mycats для настройки кластера Mycat для достижения высокой доступности. HAProxy реализует высокую доступность и балансировку нагрузки многоузлового кластера Mycat, а высокая доступность самого HAProxy может быть достигнута с помощью Keepalived.

    image-20201201112221270

серийный номер Роль айпи адрес
1 Mycat1 192.168.83.133
2 Mycat2 192.168.0.105
3 HAProxy(master) 192.168.83.133 (48066)
4 HAProxy(backup) 192.168.83.133 (48600)
5 Keepalived(master) виртуальный айпи 192.168.83.200
6 Keepalived(backup)
7 Несколько серверов mysql

Установить и настроить HAProxy

Установить

  • Распаковать, скомпилировать и установить

    #解压到/usr/local/haproxy
    tar -zxvf haproxy-2.0.19.tar.gz
    #进入解压后的目录,查看内核版本,进行编译
    cd /usr/local/haproxy/haproxy-2.0.19
    
    uname -r
    make TARGET=linux310 PREFIX=/usr/local/haproxy/haproxy-2.0.19 ARCH=x86_64
    # ARGET=linux310,内核版本,使用uname -r查看内核,如:3.10.0-514.el7,此时该参数就为linux310; #ARCH=x86_64,系统位数;
    #PREFIX=/usr/local/haprpxy #/usr/local/haprpxy,为haprpxy安装路径。
    
    #编译完成后,进行安装
    make install PREFIX=/usr/local/haproxy/haproxy-2.0.19
    
    #安装完成后,创建目录、创建HAProxy配置文件
    mkdir -p /usr/data/haproxy/
    vim /usr/local/haproxy/haproxy.conf
    
    
    #6向配置文件中插入以下配置信息,并保存
    global
     log 127.0.0.1 local0
     #log 127.0.0.1 local1 notice
     #log loghost local0 info
     maxconn 4096
     chroot /usr/local/haproxy
     pidfile /usr/data/haproxy/haproxy.pid
     uid 99
     gid 99
     daemon
     #debug
     #quiet
    defaults
     log global
      mode tcp
     option abortonclose
     option redispatch
     retries 3
     maxconn 2000
     timeout connect 5000
     timeout client 50000
     timeout server 50000
    listen proxy_status 
    bind :48066
     mode tcp
     balance roundrobin
     server mycat_1 192.168.83.133:8066 check inter 10s
     server mycat_2 192.168.0.105:8066 check inter 10s
    frontend admin_stats 
    bind :7777
     mode http
     stats enable
     option httplog
     maxconn 10
     stats refresh 30s
     stats uri /admin
     stats auth admin:123123
     stats hide-version
     stats admin if TRUE
    

Начать проверку

  • проверять

    #1启动HAProxy
    /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/haproxy.conf
    #2查看HAProxy进程
    ps -ef|grep haproxy
    #3打开浏览器访问
    http://192.168.140.125:7777/admin
    #在弹出框输入用户名:admin密码:123123
    

    image-20201201114750773

    Если и основная, и резервная машины Mycat запущены, вы можете увидеть следующий рисунок.image-20201201135402837

    #4验证负载均衡,通过HAProxy访问Mycat 48066为HAproxy配置的端口
    mysql -umycat -h 192.168.83.133 -P 48066 -p
    

    image-20201201140639534

Настроить поддержку активности

Установить Keepalived

  • Разархивируйте установочную конфигурацию

    #1.解压
    tar -zxvf keepalived-1.4.4.tar.gz 
    #2.安装依赖插件
    yum install -y gcc openssl-devel popt-devel
    #3.进入解压后的目录,进行配置,进行编译
    /usr/local/keepalived/keepalived-1.4.4
    ./configure --prefix=/usr/local/kp
    
    #4进行编译,完成后进行安装
    make && make install
    
    #5运行前配置
    cp /usr/local/keepalived/keepalived-1.4.4/keepalived/etc/init.d/keepalived /etc/init.d/
    mkdir /etc/keepalived
    cp /usr/local/kp/etc/keepalived/keepalived.conf /etc/keepalived/
    cp /usr/local/keepalived/keepalived-1.4.4/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
    cp /usr/local/kp/sbin/keepalived /usr/sbin/
    
    #6修改配置文件 (清空覆盖 注意修改自己的ip地址)
    vim /etc/keepalived/keepalived.conf
    
    • conf

      global_defs {
       notification_email {
       xlcocoon@foxmail.com
       }
       notification_email_from keepalived@showjoy.com
       smtp_server 127.0.0.1
       smtp_connect_timeout 30
       router_id LVS_DEVEL
       vrrp_skip_check_adv_addr
       vrrp_garp_interval 0
       vrrp_gna_interval 0
      }
      vrrp_instance VI_1 {
       #主机配MASTER,备机配BACKUP
      state MASTER
      #所在机器网卡
       interface ens33
      virtual_router_id 51
      #数值越大优先级越高
       priority 100
       advert_int 1
       authentication {
       auth_type PASS
       auth_pass 1111
       }
      virtual_ipaddress {
      #虚拟IP
       192.168.83.200
       }
      }
      
      virtual_server 192.168.83.200 48066 {
       delay_loop 6
       lb_algo rr
       lb_kind NAT
       persistence_timeout 50
       protocol TCP
        real_server 192.168.83.133 48066 {
       weight 1
       TCP_CHECK {
       connect_timeout 3
       retry 3
       delay_before_retry 3
       } }
      real_server 192.168.83.133 48600 {
       weight 1
       TCP_CHECK {
       connect_timeout 3
       nb_get_retry 3
       delay_before_retry 3
       }
       } 
      }
      

Начать проверку

  • #1启动Keepalived
    service keepalived start
    #2登录验证
    mysql -umycat -p123456 -h 192.168.83.200 -P 48066
    

    image-20201201150306318

проверить высокую доступность

  • Шаг 1: Закройте Mycat

  • Шаг 2: запрос данных через виртуальный IP

mysql -umycat -p123456 -h 192.168.83.200 -P 48066


![image-20201201150808036](https://img2020.cnblogs.com/blog/1875400/202012/1875400-20201202083415085-1688854723.png)





## Mycat安全设置

### 权限配置

#### user标签权限控制

* 目前Mycat对于中间件的连续控制并没有做太复杂的控制,只做了中间件逻辑库级别的读写权限控制。是通过`server.xml` 的user标签进行配置

![image-20201201152414679](https://img2020.cnblogs.com/blog/1875400/202012/1875400-20201202083415304-1861951250.png)

* 配置说明

| 标签属性 | 说明                                                         |
| -------- | ------------------------------------------------------------ |
| name     | 应用连接中间件逻辑库的用户名                                 |
| password | 该用户对应的密码                                             |
| schemas  | 应用当前连接的逻辑库。schemas中可以配置一个或多个            |
| readOnly | 应用连接中间件逻辑库所具有的权限。true为只读,false为读写都有,默认为false |



* 测试案例

* 测试一

Использовать пользователя пользователя, разрешение только для чтения (readOnly: true)

Проверьте, могут ли данные быть запрошены и могут ли данные быть записаны

Вывод: только для чтения, не для записи


![image-20201201153516985](https://img2020.cnblogs.com/blog/1875400/202012/1875400-20201202083415555-126959984.png)
* 测试二	

  ```
  #使用mycat用户,权限为可读写(readOnly:false) 
  # 验证是否可以查询出数据,验证是否可以写入数据
  
  结论:可读可写
  ```

  ![image-20201201153910542](https://img2020.cnblogs.com/blog/1875400/202012/1875400-20201202083415814-686175888.png)



#### privileges标签权限控制

* 在user标签下的`privileges`标签可以对逻辑库(schema)、表(table)进行精细化的DML权限控制

`privileges`标签下的`check`属性,如为`true`开启权限检查,为`false`不开启,默认为`false`

由于Mycat 一个用户的`schemas`属性可配置多个逻辑库(schema),所以 `privileges`的下级节点schema节点同样可配置多个,对多库多表进行细粒度的DML权限控制

```xml
#server.xml配置文件privileges部分
#配置orders表没有增删改查权限
<user name="mycat">
    <property name="password">123456</property>
    <property name="schemas">TESTDB</property>
 <!-- 表级 DML 权限设置 -->
    <privileges check="true">
        <schema name="TESTDB" dml="1111" >
            <table name="orders" dml="0000"></table>
<!--<table name="tb02" dml="1111"></table>-->
        </schema>
    </privileges>
</user>

image-20201201161036859

  • Инструкции по настройке

    Разрешения DML добавить (вставить) Обновить запрос (выбрать) удалять
    0000 запретить запретить запретить запретить
    0010 запретить запретить позволять запретить
    1110 позволять запретить запретить запретить
    1111 позволять позволять позволять позволять
  • Тестовый случай (перезапустите Mycat)

    • тест один

      使用mycat用户,privileges配置orders表权限为禁止增删改查(dml="0000")
      验证是否可以查询出数据,验证是否可以写入数据
      
      结论:orders表禁止读写,其他表可读可写
      

      image-20201201161427813

Перехват SQL

  • firewallМетки используются для определения брандмауэров;firewallВнизwhitehostМетки используются для определения белых списков IP-адресов,balckListИспользуется для определения черных списков SQL

белый список

  • Установив белый список, некоторые пользователи на одних хостах могут получить доступ к Mycat, в то время как пользователям на других хостах доступ запрещен.

    #设置白名单
    #server.xml配置文件firewall标签
    #配置只有192.168.83.133 主机可以通过mycat用户访问
    
    <firewall>
        <whitehost>
            <host host="192.168.83.133" user="mycat"/>
        </whitehost>
    </firewall>
    
  • Тест (перезапустите Mycat)

    • 192.168.0.105 доступ к Mycat (отказано, нет разрешения)

      image-20201201162523328

    • 192.168.83.133 доступ к Mycat (успешно)

      image-20201201162604613

черный список

  • Установив черный список, Mycat может перехватывать определенные операции SQL, такие как операции добавления, удаления, изменения и проверки.

    #设置黑名单
    #server.xml配置文件firewall标签
    #配置禁止mycat用户进行删除操作
    
    
    <firewall>
        <whitehost>
            <host host="192.168.140.128" user="mycat"/>
        </whitehost>
        <blacklist check="true">
            <property name="deleteAllow">false</property>
        </blacklist>
    </firewall>
    

    image-20201201163549940

  • Инструкции по настройке

    элемент конфигурации Значение по умолчанию описывать
    selectAllow true Разрешить ли выполнение операторов SELECT
    deleteAllow true Разрешить ли выполнение операторов DELETE
    updateAllow true Разрешить ли выполнение операторов обновления
    insertAllow true Разрешить ли выполнение операторов INSERT
    createTableAllow true разрешить ли создание таблицы
    setAllow true разрешить ли синтаксис SET
    alterTableAllow true Разрешить ли выполнение операторов Alter Table
    dropTableAllow true Разрешить ли изменение таблицы
    commitAllow true Разрешить ли операцию фиксации
    rollbackAllow true Разрешить ли откат операций
  • Тест (перезапустите Mycat)

    image-20201201163955652

Инструмент мониторинга Mycat

Введение в Mycat-web

  • Mycat-web — это платформа управления и мониторинга для визуальной эксплуатации и обслуживания Mycat, которая восполняет пробел в мониторинге Mycat и помогает Mycat различать

    Отвечает за статистические задачи и задачи управления конфигурацией

    Mycat-web представляет ZooKeeper как центр конфигурации, который может управлять несколькими узлами

    Mycat-web в основном управляет и отслеживает трафик Mycat, соединения, активные потоки и память и т. д. Он имеет такие модели, как белый список IP-адресов и оповещения по электронной почте.

    Блоки, также можно подсчитывать SQL и анализировать медленный SQL и высокочастотный SQL и т.д.; дают основу для оптимизации SQL

    image-20201201165220794

Использование конфигурации Mycat-web

установка зоопарка

  • Разархивируйте установку

    #1 解压
    tar -zxvf apache-zookeeper-3.6.1-bin.tar.gz 
    #2 进入ZooKeeper解压后的配置目录(conf),复制配置文件并改名
    cp zoo_sample.cfg zoo.cfg
    #3 进入ZooKeeper的命令目录(bin),运行启动命令
    ./zkServer.sh start
    #4 ZooKeeper服务端口为2181,查看服务已经启动
    netstat -ant | grep 2181
    

    image-20201201170053577

    image-20201201170147962

Mycat-веб-установка

  • адрес загрузки mycat-web

    # 解压
    tar -zxvf Mycat-web-1.0-SNAPSHOT-20170102153329-linux.tar.gz
    #启动
    ./start.sh &
    # Mycat-web服务端口为8082,查看服务已经启动
    netstat -ant | grep 8082
    # 通过地址访问服务
    http://192.168.83.133:8082/mycat/
    

    image-20201201172452151

    image-20201201172508836

    image-20201201173319474

Конфигурация Mycat-web

  • Добавить экземпляр мониторинга Mycat

    image-20201201173124870

Индикаторы мониторинга производительности Mycat

  • Анализ мониторинга

    image-20201201173102056