Maison >base de données >tutoriel mysql >Comment implémenter la réplication parallèle dans la réplication MySQL

Comment implémenter la réplication parallèle dans la réplication MySQL

王林
王林avant
2023-05-26 12:23:441780parcourir

    Instructions traditionnelles de réplication monothread

    Comme nous le savons tous, avant la version 5.6 de MySQL, il y avait deux threads sur le nœud esclave de la réplication maître-esclave, à savoir le thread d'E/S et le thread SQL.

    • Le thread d'E/S est chargé de recevoir les événements du journal binaire et de les écrire dans le journal de relais.

    • Le thread SQL lit le journal du relais et le relit dans la base de données.

    La méthode ci-dessus entraînera parfois des retards, alors quelles sont les situations qui peuvent entraîner des retards entre les nœuds maître et esclave

    • 1. La base de données principale exécute des transactions volumineuses (telles que des modifications importantes de la structure des tables) ? .

    • 2. Modifications à grande échelle de la base de données principale (telles que des opérations d'insertion, de mise à jour et de suppression à grande échelle).

    • 3. En mode de synchronisation ROW, la table principale de la base de données n'a pas de clé primaire fréquemment mise à jour.

    • 4. La configuration des paramètres de la base de données est déraisonnable et il existe un goulot d'étranglement dans les performances du nœud esclave (par exemple : le paramètre du journal des transactions du nœud esclave est trop petit, ce qui entraîne un vidage fréquent du disque).

    • 5. L'environnement réseau est instable et il y a des retards et des reconnexions dans la lecture du journal binaire à partir du thread IO du nœud.

    • 6. La configuration matérielle maître-esclave est différente et l'utilisation des ressources matérielles du nœud esclave atteint la limite supérieure. (Par exemple : disque SSD du nœud maître, disque SAS du nœud esclave)

    Vous pouvez classer grossièrement les raisons de retard ci-dessus.

    • 1. Problèmes matériels (y compris les E/S du disque, les E/S du réseau, etc.)

    • 2.

    • 3. Problèmes de conception de base de données.

    • 4. La base de données principale change en grande quantité et le traitement SQL monothread du nœud esclave n'est pas assez rapide.

    Résumé

    Après avoir analysé les raisons ci-dessus, on peut voir que afin de réduire le délai maître-esclave, en plus d'améliorer les conditions matérielles, le DBA doit également prêter attention à la conception et à la configuration de la base de données. Enfin, il est nécessaire d'améliorer les capacités de traitement simultané des nœuds esclaves, le passage d'une lecture monothread à une lecture parallèle multithread est une meilleure méthode. Le point clé est de savoir comment résoudre le problème des conflits de données et de la confirmation. de points de localisation de récupération de pannes dans le cadre d'une récupération multithread.

    MySQL5.6 est basé sur la réplication parallèle au niveau de la bibliothèque

    Lorsqu'il y a plusieurs bases de données dans l'instance, plusieurs threads peuvent être démarrés et chaque thread correspond à une base de données. Dans ce mode, le nœud esclave démarrera plusieurs threads. Les threads sont divisés en deux catégories : Coordinateur et WorkThread. Coordinator 和 WorkThread

    • 线程分工执行逻辑

    Coordinator线程负责判断事务是否可以并行执行,如果可以并行就把事务分发给WorkThread线程执行,如果判断不能执行,如DDL跨库操作等,就等待所有的worker线程执行完成之后,再由Coordinator执行。

    • 关键配置信息

    slave-parallel-type=DATABASE
    • 方案不足点

    这种并行复制的模式,只有在实例中有多个DB且DB的事务都相对繁忙的情况下才会有较高的并行度,但是日常维护中其实单个实例的的事务处理相对集中在一个DB上。大多数延迟情况都基于热点表的出现而观察得出。如果能够提供基于表的并行度是一个很好方法。

    MySQL5.7基于组提交的并行复制

    组提交说明

    简单来说就是在双1的设置下,事务提交后即刷盘的操作改为多个事务合并成一组事务再进行统一刷盘,这样处理就降低了磁盘IO的压力。详细资料参考老叶茶馆关于组提交的说明推文https://mp.weixin.qq.com/s/rcPkrutiLc93aTblEZ7sFg

    一组事务同时提交也就意味着组内事务不存在冲突,故组内的事务在从节点上就可以并发执行,问题在于如何区分事务是否在同一组中的,于是在binlog中出现了两个新的参数信息last_committed 和 sequence_number

    • 如何判断事务在一个组内呢?

    解析binlog可以发现里面多了last_committedsequence_number两个参数信息,其中last_committed存在重复的情况。

    • sequence_number # 这个值指的是事务提交的序号,单调递增。

    • last_committed

      Thread Division de la logique d'exécution du travail
    • Le thread Coordinateur est chargé de déterminer si la transaction peut être exécutée en parallèle. Si elle peut être exécutée en parallèle, la transaction sera distribuée. au thread WorkThread pour exécution. S'il est jugé qu'il ne peut pas être exécuté, comme DDL, opération entre bibliothèques, etc. , attendez que tous les threads de travail terminent l'exécution, puis exécutez-le par Coordinateur.
    • Informations de configuration clés

      🎜🎜
      [root@mgr2 GreatSQL]# mysqlbinlog mysql-bin.0000002 | grep last_committed
      GTID last_committed=0 sequence_number=1
      GTID last_committed=0 sequence_number=2
      GTID last_committed=2 sequence_number=3
      GTID last_committed=2 sequence_number=4
      GTID last_committed=2 sequence_number=5
      GTID last_committed=2 sequence_number=6
      GTID last_committed=6 sequence_number=7
      GTID last_committed=6 sequence_number=8
      🎜🎜🎜Défauts du schéma🎜🎜🎜🎜🎜Ce mode de réplication parallèle n'est disponible que lorsqu'il y a plusieurs bases de données dans l'instance et que les transactions des bases de données sont relativement occupées. Degré élevé de parallélisme, mais dans la maintenance quotidienne, le traitement des transactions d'une seule instance est relativement concentré sur une seule base de données. La plupart des retards sont observés en fonction de la présence de tables de points chauds. Ce serait une bonne idée de fournir un parallélisme basé sur des tables. 🎜🎜

      Réplication parallèle de MySQL5.7 basée sur la soumission de groupe

      Instructions de soumission de groupe

      🎜🎜En termes simples, sous le paramètre double 1, l'opération de vidage du disque après la transaction est soumis est modifié. Fusionnez plusieurs transactions en un groupe de transactions, puis effectuez un vidage unifié du disque, ce qui réduit la pression sur les E/S du disque. Pour des informations détaillées, veuillez vous référer au tweet d'explication de Laoye Teahouse sur la soumission de groupe https://mp.weixin.qq.com/s/rcPkrutiLc93aTblEZ7sFg🎜🎜🎜Un groupe des transactions sont soumises en même temps. Cela signifie qu'il n'y a pas de conflit dans les transactions au sein du groupe, donc les transactions du groupe peuvent être exécutées simultanément sur le nœud esclave. Le problème est de savoir comment distinguer si les transactions sont dans le même groupe. groupe, donc deux nouvelles informations de paramètres apparaissent dans le binlog last_commit et sequence_number🎜🎜🎜🎜Comment juger si une transaction est dans un groupe ?🎜🎜🎜🎜🎜Quand vous analysez le binlog, vous pouvez constater qu'il y a plus de last_commit et de sequence_numberDeux informations sur les paramètres, parmi lesquelles last_commit est dupliqué. 🎜🎜🎜🎜🎜sequence_number # Cette valeur fait référence au numéro de séquence de soumission de transaction, qui augmente de façon monotone. 🎜🎜🎜🎜last_commit # Cette valeur a deux significations. 1. La même valeur signifie que ces transactions sont dans le même groupe, 2. Cette valeur représente également le nombre maximum du groupe de transactions précédent. 🎜🎜🎜
      slave-parallel-type=LOGICAL_CLOCK
      🎜🎜🎜Configuration de la base de données🎜🎜🎜
      slave_parallel_type = LOGICAL_CLOCK
      slave_parallel_workers = 8
      binlog_transaction_dependency_tracking = WRITESET
      slave_preserve_commit_order = 1
      🎜🎜🎜Inadéquation du plan🎜

    基于组提交的同步有个不足点,就是当主节点的事务繁忙度较低的时候,导致时间段内组提交fsync刷盘的事务量较少,于是导致从库回放的并行度并不高,甚至可能一组里面只有一个事务,这样从节点的多线程就基本用不到,可以通过设置下面两个参数,让主节点延迟提交。

    • binlog_group_commit_sync_delay # 等待延迟提交的时间,binlog提交后等待一段时间再 fsync。让每个 group 的事务更多,人为提高并行度。

    • binlog_group_commit_sync_no_delay_count # 待提交的最大事务数,如果等待时间没到,而事务数达到了,就立即 fsync。达到期望的并行度后立即提交,尽量缩小等待延迟。

    MySQL8.0基于writeset的并行复制

    writeset 基于事务结果冲突进行判断事务是否可以进行并行回放的方法,他由binlog-transaction-dependency-tracking参数进行控制,默认采用WRITESET方法。

    关键参数查看

    Command-Line Format --binlog-transaction-dependency-tracking=value
    System Variable binlog_transaction_dependency_tracking
    Scope Global
    Dynamic Yes
    SET_VAR Hint Applies No
    Type Enumeration
    Default Value COMMIT_ORDER
    Valid Values COMMIT_ORDER
    WRITESET
    WRITESET_SESSION

    参数配置项说明

    • COMMIT_ORDER # 使用 5.7 Group commit 的方式决定事务依赖。

    • WRITESET     # 使用写集合的方式决定事务依赖。

    • WRITESET_SESSION # 使用写集合,但是同一个session中的事务不会有相同的last_committed。

    writeset 是一个HASH类型的数组,里面记录着事务的更新信息,通过transaction_write_set_extraction判断当前事务更新的记录与历史事务更新的记录是否存在冲突,判断过后再采取对应处理方法。writeset储存的最大存储值由binlog-transaction-dependency-history-size控制。

    需要注意的是,当设置成WRITESETWRITESET_SESSION的时候,事务提交是无序状态的,可以通过设置 slave_preserve_commit_order=1 强制按顺序提交。

    • binlog_transaction_dependency_history_size

    设定一个上限,限制在内存中缓存之前事务修改的行信息时所使用的行哈希数。一旦达到这个哈希数,就会清除历史记录。

    Command-Line Format --binlog-transaction-dependency-history-size=#
    System Variable binlog_transaction_dependency_history_size
    Scope Global
    Dynamic Yes
    SET_VAR Hint Applies No
    Type Integer
    Default Value 25000
    Minimum Value 1
    Minimum Value 1000000
    • transaction_write_set_extraction

    该模式支持三种算法,默认采用XXHASH64,当从节点配置writeset复制的时候,该配置不能配置为OFF。在MySQL 8.0.26中,该参数已被标记为已弃用,将来将被删除。

    Command-Line Format --transaction-write-set-extraction[=value]
    Deprecated 8.0.26
    System Variable binlog_transaction_dependency_history_size
    Scope Global, Session
    Dynamic Yes
    SET_VAR Hint Applies No
    Type Enumeration
    Default Value XXHASH64
    Valid Values OFF
    MURMUR32
    XXHASH64

    数据库配置

    slave_parallel_type = LOGICAL_CLOCK
    slave_parallel_workers = 8
    binlog_transaction_dependency_tracking = WRITESET
    slave_preserve_commit_order = 1

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer