Используйте canal+kafka для мониторинга небольшой практики MySQL binlog

MySQL

предисловие

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

  • Используемые инструменты: MySQL + Canal + Kafka

1. Кафка:kafka.apache.org/быстрый старт(…2. Канал:GitHub.com/Alibaba/Misery…3. Версия MySQL выглядит следующим образом:

+-------------------------+-----------------------+
| Variable_name           | Value                 |
+-------------------------+-----------------------+
| innodb_version          | 8.0.12                |
| protocol_version        | 10                    |
| slave_type_conversions  |                       |
| tls_version             | TLSv1,TLSv1.1,TLSv1.2 |
| version                 | 8.0.12                |
| version_comment         | Homebrew              |
| version_compile_machine | x86_64                |
| version_compile_os      | osx10.14              |
| version_compile_zlib    | 1.2.11                |
+-------------------------+-----------------------+

Профиль бинарного журнала MySQL

  • Binlog — это двоичный журнал, поддерживаемый уровнем сервера MySQL, который полностью отличается от журнала повторов/отмен в механизмах хранения, таких как innodb; он в основном используется для записи операторов SQL, которые обновляют или потенциально обновляют данные MySQL, и использует «транзакции». ” хранится на диске. Затем функция журнала binlog выглядит следующим образом:

репликация master-slave Восстановление данных Инкрементное резервное копирование

  • Просмотр конфигурации, связанной с binlog:show variables like '%log_bin%';
+---------------------------------+-----------------------------------+
| Variable_name                   | Value                             |
+---------------------------------+-----------------------------------+
| log_bin                         | ON                                |
| log_bin_basename                | /usr/local/var/mysql/binlog       |
| log_bin_index                   | /usr/local/var/mysql/binlog.index |
| log_bin_trust_function_creators | OFF                               |
| log_bin_use_v1_row_events       | OFF                               |
| sql_log_bin                     | ON                                |
+---------------------------------+-----------------------------------+
  • Просмотрите каталог binlog:show binary logs;
+---------------+-----------+
| Log_name      | File_size |
+---------------+-----------+
| binlog.000036 |       155 |
| binlog.000037 |      1066 |
| binlog.000038 |      3075 |
+---------------+-----------+
  • Проверить состояние бинлога:show master status;Вы можете просматривать информацию о состоянии текущего двоичного файла журнала, отображать записываемый связанный файл, а также текущую позицию.
| binlog.000038 |     3075 |              |                  |                 |
  • Тогда посмотри сноваbinlog.000038содержание журнала,./mysqlbinlog /usr/local/var/mysql/binlog.000038.
  • ROWПод уровнем необходимо расшифровать оператор SQL и добавить параметр декодирования../mysqlbinlog --base64-output=decode-rows -v /usr/local/var/mysql/binlog.000038.
# at 3311
#200410 17:29:47 server id 1  end_log_pos 3386 CRC32 0xac866698 	Write_rows: table id 65 flags: STMT_END_F
### INSERT INTO `zacblog`.`t_zb_article`
### SET
###   @1=5
###   @2=22121
###   @3='dada'
###   @4='dadwad'
###   @5=0
###   @6='2020-04-10 17:29:31'
###   @7=1586510981
  • Конечно формат бинлога тоже можно задать соответственноROW,STATEMENT,MIXEDопции.

Непротиворечивость кэша и базы данных

  • Прежде всего, согласно теории CAP, система не может одновременно удовлетворять требованиям C, A и P. Отказ от C означает не отказ от согласованности, а отказ от сильной согласованности и стремление кокончательная согласованность.
  • Ранее проект также столкнулся с проблемой, как поддерживать согласованность между кешем и базой данных.В Интернете есть разные ответы, но я видел, что некоторые великие боги часто цитируютCache-Aside patternЭта статья, модель в статье естьСначала обновите базу данных, затем удалите кеш..

Порядок шагов важен. Обновляйте хранилище данных перед удалением элемента из кэша. Если сначала удалить кэшированный элемент, существует небольшой промежуток времени, когда клиент может получить элемент до обновления хранилища данных. приведет к промаху кеша (поскольку элемент был удален из кеша), в результате чего более ранняя версия элемента будет извлечена из хранилища данных и добавлена ​​обратно в кеш. Результатом будут устаревшие данные кеша. Перевод: если кеш будет удален первым, будет короткое временное окно, клиент получит доступ к старому значению базы данных, и все запросы под ключом будут отправлены в базу данных, а затем старое значение будет сохранено в опять кеш.

enter image description here

  • Потом, когда база обновится и удаление кеша не удастся (вероятность нельзя сказать, что нет), проблемы все равно будут. . .

1. Можно использовать механизм повторных попыток MQ.Когда удаление вызывает исключение, мы можем использовать MQ для повторной попытки удаления асинхронно. 2. Используйте мониторинг для обнаружения исключений повторных попыток.

  • Написав это, я чуть ли не чувствую, что отвлекся от темы, ведь эта часть интернета высказывает свое мнение, а вышеизложенное носит сугубо личный характер. Далее для удовлетворения личного любопытства.Есть статья о том,что MQ используется для мониторингаMySQL binlogУдаление асинхронного удаления, удаление не может продолжаться в MQ TRY.

Введение в канал

  • контролироватьMySQL binlogя нашелАрхитектура и практика синхронизации данных Meituan DB с хранилищем данныхВ статье написано об использованииCanalвыполнитьbinlogприбытьKafkaСвязь.
  • CanalПеревод означает водный путь / труба / канава.Основная цель - анализировать инкрементные журналы на основе базы данных MySQL и обеспечивать подписку и потребление инкрементных данных.
  • Услуги, основанные на добавочной подписке и потреблении журналов, включают

1. Зеркальное отображение базы данных 2. Резервное копирование базы данных в реальном времени 3. Построение индекса и обслуживание в режиме реального времени (разделенный гетерогенный индекс, инвертированный индекс и т. д.) 4. Обновление бизнес-кэша 5. Инкрементальная обработка данных с бизнес-логикой

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

1. Сначала запустите кафку 2. Canal instance.properties и canal.properties, включая базу данных, информацию о пользователе, кластер Kafka и информацию о теме. 3. В соответствии с информацией о конфигурации Canal создайте соответствующие темы и потребителей в Kafka.

Побить пит-рекорд

  • canal.propertiesключевая конфигурация
...
canal.serverMode = kafka
...
canal.mq.servers = localhost:9092,localhost:9093,localhost:9094
  • instance.propertiesключевая конфигурация
canal.instance.master.address=192.168.1.20:3306
# username/password,数据库的用户名和密码
...
canal.instance.dbUsername = canal
canal.instance.dbPassword = canal
...
# mq config
canal.mq.topic=example
  • caching_sha2_password Auth failed
Caused by: java.io.IOException: connect /127.0.0.1:3306 failure
	at com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.connect(MysqlConnector.java:83) ~[canal.parse.driver-1.1.4.jar:na]
	at com.alibaba.otter.canal.parse.inbound.mysql.MysqlConnection.connect(MysqlConnection.java:89) ~[canal.parse-1.1.4.jar:na]
	at com.alibaba.otter.canal.parse.inbound.mysql.MysqlEventParser.preDump(MysqlEventParser.java:86) ~[canal.parse-1.1.4.jar:na]
	at com.alibaba.otter.canal.parse.inbound.AbstractEventParser$3.run(AbstractEventParser.java:183) ~[canal.parse-1.1.4.jar:na]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]
Caused by: java.io.IOException: caching_sha2_password Auth failed
	at com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.negotiate(MysqlConnector.java:257) ~[canal.parse.driver-1.1.4.jar:na]
	at com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.connect(MysqlConnector.java:80) ~[canal.parse.driver-1.1.4.jar:na]
	... 4 common frames omitted
  • использоватьmysql -hlocalhost -P3306 -ucanal -p123 -DzacblogВойдите в базу данных, перезапуститеcanalВот и все.

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

  • Согласно модификации таблицы базы данных, Canal отправит сообщение через Kafka, а формат сообщения, полученного Потребителем, будет следующим.
  • ВСТАВИТЬ заявление,dataключевое поле
{
    "data":[
        {
            "article_id":"3",
            "author_id":"1121212",
            "article_title":"dadad",
            "article_content":"dadad",
            "status":"0",
            "create_time":"2020-04-10 16:30:53",
            "update_time":"2020-04-10 16:31:00"
        }
    ],
    "database":"zacblog",
    "es":1586507462000,
    "id":1,
    "isDdl":false,
    "mysqlType":{
        "article_id":"bigint(20)",
        "author_id":"bigint(20)",
        "article_title":"varchar(50)",
        "article_content":"text",
        "status":"tinyint(3)",
        "create_time":"datetime",
        "update_time":"timestamp"
    },
    "old":null,
    "pkNames":[
        "article_id"
    ],
    "sql":"",
    "sqlType":{
        "article_id":-5,
        "author_id":-5,
        "article_title":12,
        "article_content":2005,
        "status":-6,
        "create_time":93,
        "update_time":93
    },
    "table":"t_zb_article",
    "ts":1586507463069,
    "type":"INSERT"
}
  • Оператор UPDATE, обновите поля с помощьюoldсписок для представления
{
	...
    "old":[
        {
            "article_title":"dadad",
            "update_time":"2020-04-10 16:31:00"
        }
    ],
	...
    "type":"UPDATE"
}
  • УДАЛИТЬ заявление,dataключевое поле
{
	...
    "data":[
        {
            "article_id":"5",
            "author_id":"22121",
            "article_title":"dada",
            "article_content":"dadwad",
            "status":"0",
            "create_time":"2020-04-10 17:29:31",
            "update_time":"2020-04-10 17:29:41",
            "ext":null
        }
    ],
    "database":"zacblog",
    "es":1586517722000,
	...
    "type":"DELETE"
}
  • ALTER TABLE, непосредственно инструкция
{
    "data":null,
    "database":"zacblog",
    "es":1586511807000,
    "id":6,
    "isDdl":true,
    "mysqlType":null,
    "old":null,
    "pkNames":null,
    "sql":"ALTER TABLE `zacblog`.`t_zb_article` 
ADD COLUMN `ext` varchar(255) NULL AFTER `update_time`",
    "sqlType":null,
    "table":"t_zb_article",
    "ts":1586511808016,
    "type":"ALTER"
}

резюме

  • Эта статья изMySQL binlogНачал, подошёл к обсуждению непротиворечивости кеша-базы, и наконец, ради удовлетворения любопытства, просто послушал.binlogМодифицированное сообщение Кафки.
  • Фактически, в реальной разработке мы также можем ссылаться на этот формат сообщения, добавлять, удалять и изменять базу данных и отправлять соответствующие бизнес-сообщения.Я думаю, что этот формат сообщения все еще полезен для справки.

Справочная статья