Introduction à TIDB et introduction au déploiement, aux principes et à l'utilisation de TIDB

Introduction à TiDB et introduction au déploiement, aux principes et à l'utilisation de TiDB

De l'architecture MySQL à TiDB

Classement de la base de données

Avant de présenter la base de données TiDB, introduisons d'abord les scénarios d'utilisation. Il existe aujourd’hui de nombreux types de bases de données : RDBMS (base de données relationnelle), NoSQL (Not Only SQL) et NewSQL, qui ont toutes leur place dans le domaine des bases de données. On peut dire qu’une centaine d’écoles de pensée s’affrontent. Alors pourquoi devrions-nous apprendre à utiliser TiDB ? Commençons ensuite par l’utilisation de MySQL, que nous connaissons le mieux.

Points faibles de MySQL

​ Supposons qu'il existe une société Internet en développement rapide. Le volume de données de la base de données de base MySQL a atteint près de 100 millions de lignes et continue de croître. L'entreprise attache une grande importance aux actifs de données. Toutes les données nécessitent plusieurs copies pour être stockées pendant au moins 5 ans, et en plus de l'activité de reporting hors ligne qui effectue des analyses statistiques sur les données historiques, il existe également certains besoins en matière d'interrogation en temps réel des données utilisateur.

​Selon l'expérience d'utilisation passée de MySQL, MySQL a de meilleures performances lorsqu'une seule table contient moins de 50 millions de lignes. Une fois qu'une seule table dépasse 50 millions de lignes, les performances et la maintenabilité de la base de données chuteront considérablement. Bien sûr, vous pouvez créer une sous-base de données et une table MySQL à ce stade, par exemple en utilisant Mycat ou Sharding-jdbc.

Sous-base de données et table MySQL

Les avantages de la sous-base de données et de la table MySQL sont très évidents

  • En divisant une grande table en petites tables, le volume de données d'une seule table peut être contrôlé à moins de 50 millions de lignes, ce qui rend les performances de MySQL stables et contrôlables.

  • Après avoir divisé une seule grande table en petites tables, elle peut être étendue horizontalement et déployée sur plusieurs serveurs pour améliorer les indicateurs de service de base de données tels que le QPS, le TPS et la latence de l'ensemble du cluster.

Les défauts de la sous-base de données et de la sous-table MySQL sont également très évidents.

  • Une fois la table divisée entre les instances, des problèmes de gestion des transactions distribuées surviennent. Une fois le serveur de base de données en panne, il existe un risque d'incohérence des transactions.

  • Une fois le tableau divisé, certaines restrictions s'appliquent aux instructions SQL, ce qui réduit considérablement les exigences fonctionnelles du côté métier. Les restrictions sont très importantes, notamment pour les besoins de rapports statistiques en temps réel.

  • Une fois la table divisée, les objets à maintenir augmentent de façon exponentielle (le nombre d'instances MySQL, le nombre de modifications SQL à effectuer, etc.)

Solutions aux problèmes MySQL

Sur la base des principaux problèmes ci-dessus, nous devons explorer de nouvelles solutions technologiques de bases de données pour faire face aux défis posés par la croissance explosive de l'entreprise et fournir un meilleur support de services de bases de données à l'entreprise.
Après avoir étudié les principales bases de données du marché, nous pouvons envisager d'utiliser la technologie NewSQL pour résoudre le problème, car la technologie NewSQL présente les principales caractéristiques suivantes :

  • Évolutivité horizontale illimitée
  • Une forte cohérence distribuée garantit une sécurité des données à 100 %
  • Capacités complètes de traitement des transactions distribuées et fonctionnalités ACID

La base de données TiDB GitHub peut être considérée comme un projet open source international en termes d'activité et de contributeurs communautaires, et est un produit représentatif de la technologie NewSQL, nous pouvons donc choisir d'utiliser la base de données TiDB !

Quatre scénarios d'application principaux

  1. Scénarios avec des attributs du secteur financier qui nécessitent une cohérence et une fiabilité élevées des données, une disponibilité élevée du système, une évolutivité et une reprise après sinistre

Comme nous le savons tous, le secteur financier a des exigences élevées en matière de cohérence et de fiabilité des données, de disponibilité élevée du système, d’évolutivité et de reprise après sinistre. La solution traditionnelle est que deux salles informatiques dans la même ville fournissent des services et qu'une salle informatique dans un autre endroit fournit des capacités de reprise après sinistre des données mais ne fournit pas de services. Cette solution présente les inconvénients suivants : faible utilisation des ressources, coûts de maintenance élevés, RTO ( Recovery Time Objective) et RPO (Recovery Point Objective) ne peuvent pas véritablement atteindre la valeur attendue par l’entreprise. TiDB utilise le protocole multi-copie + Multi-Raft pour planifier les données vers différentes salles informatiques, racks et machines. Lorsque certaines machines tombent en panne, le système peut automatiquement basculer pour garantir que le RTO du système <= 30 s et le RPO = 0.

  1. Scénarios OLTP de données massives et à haute concurrence qui nécessitent une capacité de stockage, une évolutivité et une concurrence élevées

​ Avec le développement rapide des affaires, les données ont connu une croissance explosive. Les bases de données autonomes traditionnelles ne peuvent pas répondre aux exigences de capacité de la base de données en raison de la croissance explosive des données. Une solution réalisable consiste à utiliser des produits middleware avec des bases de données et des tables séparées ou NewSQL. des bases de données pour remplacer ou utiliser des bases de données haut de gamme, des périphériques de stockage, etc. La plus rentable d'entre elles est la base de données NewSQL, comme TiDB. TiDB adopte une architecture de séparation de calcul et de stockage, qui peut respectivement étendre et réduire le calcul et le stockage. L'informatique prend en charge un maximum de 512 nœuds, chaque nœud prend en charge un maximum de 1 000 simultanéités et la capacité du cluster prend en charge un maximum de niveau PB.

  1. Scénario HTAP en temps réel

​ Avec le développement rapide de la 5G, de l'Internet des objets et de l'intelligence artificielle, les entreprises produiront de plus en plus de données, et leur échelle pourrait atteindre des centaines de To, voire des niveaux de Po. La solution traditionnelle consiste à traiter les transactions en ligne via des bases de données OLTP. , les données sont synchronisées avec la base de données OLAP pour l'analyse des données via des outils ETL. Cette solution de traitement présente de nombreux problèmes tels qu'un coût de stockage élevé et de mauvaises performances en temps réel. TiDB a introduit le moteur de stockage en colonnes TiFlash dans la version 4.0 et l'a combiné avec le moteur de stockage en lignes TiKV pour créer une véritable base de données HTAP. Avec une légère augmentation des coûts de stockage, le traitement des transactions en ligne et l'analyse des données en temps réel peuvent être effectués dans le même système. , ce qui permet d'économiser considérablement les coûts des entreprises.

  1. Scénarios d’agrégation de données et de traitement secondaire

​Actuellement, les données commerciales de la plupart des entreprises sont dispersées dans différents systèmes sans résumé unifié. À mesure que l'entreprise se développe, le niveau décisionnel de l'entreprise doit comprendre la situation commerciale de l'ensemble de l'entreprise afin de prendre des décisions en temps opportun. il est nécessaire d'intégrer les données dispersées dans Les données des différents systèmes sont rassemblées dans le même système et traitées deux fois pour générer des rapports T+0 ou T+1. La solution courante traditionnelle consiste à utiliser ETL + Hadoop, mais le système Hadoop est trop complexe et les coûts d'exploitation, de maintenance et de stockage sont trop élevés pour répondre aux besoins des utilisateurs. Par rapport à Hadoop, TiDB est beaucoup plus simple. Les entreprises synchronisent les données avec TiDB via des outils ETL ou des outils de synchronisation TiDB. Les rapports peuvent être directement générés dans TiDB via SQL.

Résumer

​ Les bases de données relationnelles traditionnelles ont une longue histoire. Actuellement, les SGBDR sont représentés par Oracle, MySQL et PostgreSQL. Ils sont également relativement avancés dans le domaine des bases de données. Ils sont largement utilisés dans tous les domaines. La plupart des SGBDR sont des systèmes de stockage local ou partagés. stockage.
​ Cependant, ce type de base de données présente certains problèmes, tels que ses propres limitations de capacité. À mesure que le volume d'activité continue d'augmenter, la capacité devient progressivement un goulot d'étranglement. À ce stade, l'administrateur de base de données effectuera plusieurs partitionnements des tables de base de données pour atténuer le problème de capacité. Un grand nombre de sous-bases de données et de sous-tables consomment non seulement beaucoup de main d'œuvre, mais compliquent également la logique de routage pour l'accès des entreprises à la base de données. De plus, le SGBDR a une faible évolutivité, le coût d'expansion et de contraction du cluster est généralement élevé et il ne répond pas aux besoins des transactions distribuées.
Les représentants des bases de données NoSQL sont Hbase, Redis, MongoDB, Cassandra, etc. Ce type de base de données résout le problème de la mauvaise évolutivité du SGBDR et l'expansion de la capacité du cluster devient beaucoup plus pratique. Cependant, comme la méthode de stockage est un stockage multi-KV, il est non compatible avec SQL. Le sexe est grandement compromis. Pour les bases de données NoSQL, elles ne peuvent répondre qu'à certaines caractéristiques des transactions distribuées.
Les représentants dans le domaine NewSQL sont Google's spanner et F1, qui prétendent être capables de réaliser une reprise après sinistre mondiale du centre de données et de répondre pleinement à l'ACID des transactions distribuées, mais ils ne peuvent être utilisés que sur Google Cloud. TiDB est né dans un contexte général et a également comblé le vide dans le domaine national du NewSQL. Depuis que TiDB a écrit sa première ligne de code en mai 2015, il a publié des dizaines de versions, grandes et petites, et les itérations de versions sont très rapides.

Introduction à la base de données TiDB

Présentation de la TiDB

Site officiel de la base de données TiDB : https://pingcap.com/zh/

TiDB est une base de données relationnelle distribuée open source conçue et développée indépendamment par PingCAP. Il s'agit d'un produit de base de données distribuée convergée qui prend en charge à la fois le traitement des transactions en ligne et le traitement analytique en ligne (traitement transactionnel et analytique hybride, HTAP). Il a une expansion horizontale ou il a d'importantes des fonctionnalités telles que la réduction de capacité, la haute disponibilité de qualité financière, le HTAP en temps réel, la base de données distribuée cloud native, la compatibilité avec le protocole MySQL 5.7 et l'écosystème MySQL. L’objectif est de fournir aux utilisateurs des solutions uniques OLTP (Online Transactional Processing), OLAP (Online Analytical Processing) et HTAP. TiDB convient à divers scénarios d'application tels que la haute disponibilité, de fortes exigences de cohérence et une grande échelle de données.

Classification et tri des bases de données

SQL, NoSQL, NewSQL

SQL

Bases de données relationnelles (SGBDR, base de données SQL)
Logiciels commerciaux : Oracle, DB2
Logiciels open source : MySQL, PostgreSQL
La version autonome rencontrée par les bases de données relationnelles a été difficile à répondre aux besoins de données massives.

NoSQL

NoSQL = Not Only SQL, qui signifie « pas seulement SQL », préconise l'utilisation d'un stockage de données non relationnel. Il est
généralement choisi de sacrifier la prise en charge de transactions SQL et ACID complexes en échange de capacités d'expansion élastiques.
Cela ne garantit généralement pas une forte cohérence (supporte une cohérence éventuelle)
.

  • Base de données clé-valeur : telle que MemcacheDB, Redis
  • Stockage de documents : tel que MongoDB
  • Stockage de colonnes : pratique pour stocker des données structurées et semi-structurées et effectuer une compression de données. Il présente de grands avantages en matière d'E/S pour interroger certaines colonnes : telles que HBase, Cassandra.
  • Base de données graphique : stocke les relations graphiques (remarque : pas d'images). Comme Neo4J
NouveauSQL

Pour la lecture et l'écriture OLTP, il offre la même évolutivité et les mêmes performances que NOSQL, tout en prenant en charge les transactions qui répondent aux caractéristiques ACID, c'est-à-dire en maintenant la haute évolutivité et les hautes performances de NoSQL et en maintenant le modèle relationnel.Pourquoi NewSQL est-il nécessaire
?

  • NoSQL ne peut pas remplacer complètement le SGBDR

  • Le SGBDR autonome ne peut pas répondre aux exigences de performances

  • En utilisant l'approche « SGBDR autonome + middleware », il est difficile de résoudre les transactions distribuées et les problèmes de haute disponibilité au niveau de la couche middleware.

Nouvelle architecture de conception SQL

  • Il peut être basé sur une nouvelle plate-forme de base de données ou sur l'optimisation d'un moteur SQL existant.
  • Aucun stockage partagé (architecture MPP) n'est une architecture relativement courante
  • Mettre en œuvre la haute disponibilité et la reprise après sinistre sur la base de plusieurs copies
  • Requête distribuée
  • Mécanisme de partage de données
  • Assurer la cohérence des données grâce à 2PC, Paxos/Raft et d'autres protocoles

Produits représentatifs

  • Clé Google
  • OcéanBase
  • TiDB

OLTP、OLAP

OLTP
  • Il met l'accent sur la capacité de prendre en charge un grand nombre d'opérations de transaction simultanées (ajout, suppression, modification et requête) sur une courte période de temps, et la quantité de données impliquées dans chaque opération est très faible (par exemple des dizaines à des centaines d'octets). )

  • Accent mis sur une forte cohérence des transactions (telles que les transactions de virement bancaire, tolérance zéro pour les erreurs)

Par exemple : lors de "Double Eleven", des centaines de milliers d'utilisateurs peuvent passer des commandes dans la même seconde. La base de données back-end doit être capable de traiter ces demandes de commande simultanément et à une vitesse quasiment en temps réel.

OLAP
  • Préfère les requêtes complexes en lecture seule, lisant des données massives pour l'analyse et le calcul, et le temps de requête est souvent très long

Par exemple : une fois le "Double Eleven" terminé, les opérateurs de Taobao analysent et exploitent les commandes pour découvrir certaines règles du marché, etc. Ce type d'analyse peut nécessiter la lecture de tous les ordres historiques pour le calcul, ce qui peut prendre des dizaines de secondes, voire des dizaines de minutes.

  • Produits représentatifs OLAP :
    • Prune Verte
    • TeraData
    • Base de données analytique Alibaba

La naissance de TiDB

Huang Dongxu, auteur du célèbre service de cache distribué open source Codis, co-fondateur et directeur technique de PingCAP et ingénieur d'infrastructure senior, est doué pour la conception et la mise en œuvre de systèmes de stockage distribués et est un gourou technique parmi les passionnés d'open source. Même aujourd’hui, alors qu’Internet est si prospère, dans le domaine flou et incertain des bases de données, il essaie encore de trouver une certaine direction pratique.
Fin 2012, il a vu deux articles publiés par Google, qui reflétaient comme un prisme le faible éclat de son propre cœur. Ces deux articles décrivent F1/Spanner, une donnée relationnelle massive utilisée en interne par Google, qui résout les problèmes de bases de données relationnelles, d'expansion élastique et de distribution mondiale, et est utilisée à grande échelle en production. " Si cela peut être réalisé, cela perturbera le domaine du stockage de données. " Huang Dongxu était enthousiasmé par l'émergence de la solution parfaite, et la TiDB de PingCAP est née sur cette base.

Caractéristiques architecturales de TiDB

Architecture globale de TiDB

​Le cluster TiDB comprend principalement trois composants principaux : le serveur TiDB, le serveur PD et le serveur TiKV. De plus, il existe des composants TiSpark pour répondre aux besoins OLAP complexes des utilisateurs et des composants TiDB Operator pour simplifier la gestion du déploiement cloud.

En tant que nouvelle génération de base de données NewSQL, TiDB a progressivement pris pied dans le domaine des bases de données. Il combine les fonctionnalités exceptionnelles d'Etcd/MySQL/HDFS/HBase/Spark et d'autres technologies. Avec la promotion à grande échelle de TiDB, il va progressivement affaiblir les avantages des limites OLTP/OLAP et simplifier le processus ETL complexe actuel, déclenchant une nouvelle vague technologique. En un mot, TiDB a un avenir brillant et prometteur.

Schéma d'architecture TiDB

Serveur TiDB

TiDB Server est chargé de recevoir les requêtes SQL, de traiter la logique liée à SQL, de trouver l'adresse TiKV qui stocke les données requises pour le calcul via PD Server, d'interagir avec TiKV pour obtenir des données et enfin de renvoyer les résultats. Le serveur TiDB est sans état. Il ne stocke pas les données lui-même. Il est uniquement responsable du calcul. Il peut être étendu à l'infini horizontalement et peut fournir une adresse d'accès unifiée au monde extérieur grâce à des composants d'équilibrage de charge (tels que LVS, HAProxy ou F5).

Serveur PD

Placement Driver (PD en abrégé) est le module de gestion de l'ensemble du cluster. Il a trois tâches principales :

  • La première consiste à stocker les méta-informations du cluster (sur quel nœud TiKV une certaine clé est stockée) ;

  • La seconde consiste à planifier et à équilibrer la charge du cluster TiKV (comme la migration des données, la migration du chef de groupe Raft, etc.) ;

  • La troisième consiste à attribuer un identifiant de transaction unique et croissant à l’échelle mondiale.

PD assure la sécurité des données grâce au protocole Raft. Le serveur leader de Raft est responsable du traitement de toutes les opérations, et les serveurs PD restants ne sont utilisés que pour garantir la haute disponibilité. Il est recommandé de déployer un nombre impair de nœuds PD

Serveur TiKV

TiKV Server est responsable du stockage des données. De l'extérieur, TiKV est un moteur de stockage de valeurs-clés distribué qui fournit des transactions. L'unité de base de stockage des données est la région. Chaque région est responsable du stockage des données d'une plage de clés (plage fermée à gauche et ouverte à droite de StartKey à EndKey). Chaque nœud TiKV est responsable de plusieurs régions. TiKV utilise le protocole Raft pour la réplication afin de maintenir la cohérence des données et la reprise après sinistre. Les répliques sont gérées en unités de région. Plusieurs régions sur différents nœuds forment un groupe de radeau et sont des répliques les unes des autres. L'équilibrage de charge des données entre plusieurs TiKV est planifié par PD, qui est également planifié dans les unités régionales.

TiSpark

​ TiSpark, en tant que composant principal de TiDB pour répondre aux besoins OLAP complexes des utilisateurs, exécute Spark SQL directement sur la couche de stockage TiDB, tout en intégrant les avantages des clusters distribués TiKV et en s'intégrant dans l'écosystème de la communauté Big Data. À ce stade, TiDB peut prendre en charge à la fois OLTP et OLAP via un système, éliminant ainsi le souci de synchronisation des données utilisateur.

Opérateur TiDB

TiDB Operator offre la possibilité de déployer et de gérer des clusters TiDB sur une infrastructure cloud grand public (Kubernetes). Il combine les meilleures pratiques d'orchestration de conteneurs dans la communauté cloud native avec les connaissances professionnelles en matière d'exploitation et de maintenance de TiDB, intégrant le déploiement en un clic, le co-déploiement multicluster, l'exploitation et la maintenance automatiques, l'auto-réparation des pannes et d'autres capacités, ce qui réduit considérablement le seuil permettant aux utilisateurs d'utiliser et de gérer TiDB et le coût

Fonctionnalités principales de TiDB

TiDB possède de nombreuses fonctionnalités comme suit, dont deux sont des fonctionnalités principales : l'expansion horizontale et la haute disponibilité.

Hautement compatible avec MySQL

Dans la plupart des cas, vous pouvez facilement migrer de MySQL vers TiDB sans modifier le code. Le cluster MySQL après le partitionnement de la base de données et des tables peut également être migré en temps réel via l'outil TiDB. Lorsque les utilisateurs l'utilisent, ils peuvent passer de MySQL à TiDB de manière transparente, mais le backend du « nouveau MySQL » dispose d'un stockage « illimité » et n'est plus limité par la capacité du disque local. Pendant l'exploitation et la maintenance, TiDB peut également être utilisé comme base de données esclave et lié à l'architecture maître-esclave MySQL.

Transactions distribuées

TiDB 100 % prend en charge les transactions ACID standard.

Solution HTAP unique

HTAP : traitement transactionnel/analytique hybride
TiDB est une base de données de stockage de lignes OLTP typique dotée de puissantes performances OLAP. Avec TiSpark, il peut fournir une solution HTAP unique. Un stockage peut traiter OLTP et OLAP en même temps, sans avoir besoin de processus ETL traditionnel et fastidieux.

Base de données SQL native du cloud

TiDB est une base de données conçue pour le cloud. Elle prend en charge les cloud publics, les cloud privés et les cloud hybrides. Elle peut réaliser une exploitation et une maintenance automatisées avec le projet TiDB Operator, rendant le déploiement, la configuration et la maintenance très simples.

Expansion élastique horizontale

En ajoutant simplement de nouveaux nœuds, vous pouvez réaliser une expansion horizontale de TiDB, augmenter le débit ou le stockage à la demande et faire face facilement à des scénarios de forte concurrence et de données massives.

Véritable haute disponibilité de qualité financière

Comparé au schéma de réplication maître-esclave (MS) traditionnel, le protocole d'élection majoritaire basé sur Raft peut fournir une garantie de cohérence des données à 100 % au niveau financier et peut réaliser une récupération automatique après une panne sans perdre la plupart des copies (basculement automatique) sans manuel. intervention

∩Fonctionnalités principales - Expansion horizontale∩

L'expansion horizontale illimitée est une caractéristique majeure de TiDB. L'expansion horizontale mentionnée ici comprend deux aspects : la puissance de calcul (TiDB) et la capacité de stockage (TiKV).

  • Le serveur TiDB est responsable du traitement des requêtes SQL. À mesure que votre entreprise se développe, vous pouvez simplement ajouter des nœuds du serveur TiDB pour améliorer les capacités de traitement globales et fournir un débit plus élevé.

  • TiKV est responsable du stockage des données. À mesure que la quantité de données augmente, davantage de nœuds du serveur TiKV peuvent être déployés pour résoudre le problème d'échelle des données.

  • PD planifiera entre les nœuds TiKV dans les unités régionales et migrera certaines données vers les nœuds nouvellement ajoutés.

Par conséquent, au début de l'activité, vous ne pouvez déployer qu'un petit nombre d'instances de service (il est recommandé de déployer au moins 3 TiKV, 3 PD et 2 TiDB). À mesure que le volume d'activité augmente, les instances TiKV ou TiDB peuvent être ajoutés au besoin.

∩Fonctionnalités principales – Haute disponibilité∩

La haute disponibilité est une autre fonctionnalité majeure de TiDB.Les trois composants de TiDB/TiKV/PD peuvent tolérer la panne de certaines instances sans affecter la disponibilité de l'ensemble du cluster. Ce qui suit décrit la disponibilité de ces trois composants, les conséquences d'une défaillance d'une seule instance et comment procéder à la récupération.
TiDB
TiDB est sans état. Il est recommandé de déployer au moins deux instances. Le front-end fournit des services externes via le composant d'équilibrage de charge. Lorsqu'une seule instance échoue, cela affectera la session en cours d'exécution sur cette instance. Du point de vue de l'application, une seule demande échouera. Vous pouvez continuer à obtenir des services après vous être reconnecté. Après l'échec d'une instance, vous pouvez redémarrer l'instance ou déployer une nouvelle instance.

PD
PD est un cluster qui maintient la cohérence des données via le protocole Raft. Lorsqu'une seule instance échoue, si l'instance n'est pas le leader de Raft, le service ne sera pas affecté du tout ; si l'instance est le leader de Raft, un nouveau Raft sera réélu leader, rétablit automatiquement les services. PD ne peut pas fournir de services externes pendant le processus électoral, qui prend environ 3 secondes. Il est recommandé de déployer au moins trois instances PD. Après l'échec d'une seule instance, redémarrez l'instance ou ajoutez une nouvelle instance.

TiKV
TiKV est un cluster qui maintient la cohérence des données via le protocole Raft (le nombre de copies est configurable et trois copies sont enregistrées par défaut) et effectue la planification de l'équilibrage de charge via PD. Lorsqu'un seul nœud tombe en panne, cela affectera toutes les régions stockées sur ce nœud. Pour le nœud Leader de la Région, le service sera interrompu et attendra sa réélection ; pour le nœud Follower de la Région, le service ne sera pas affecté. Lorsqu'un nœud TiKV tombe en panne et ne peut pas être récupéré dans un délai donné (30 minutes par défaut), PD migrera les données qu'il contient vers d'autres nœuds TiKV.

Capacité de stockage et puissance de calcul TiDB

Capacité de stockage-TiKV-LSM

​ Le serveur TiKV est généralement 3+. TiDB a 3 copies de chaque donnée par défaut. Ceci est quelque peu similaire à HDFS, mais les données sont répliquées via le protocole Raft. Les données sur le serveur TiKV sont effectuées en unités de région et sont contrôlées par Serveur PD. Le cluster effectue une planification unifiée, similaire à la planification régionale de HBASE.
Le format de données stocké dans le cluster TiKV est KV. Dans TiDB, les données ne sont pas stockées directement sur le disque dur/SSD, mais une solution de stockage localisée au niveau de la To est implémentée via RocksDB. Le point important à mentionner est : RocksDB et HBASE Dans le De la même manière, les arbres LSM sont utilisés comme solutions de stockage, ce qui évite un grand nombre de lectures et d'écritures aléatoires causées par l'expansion des nœuds feuilles de l'arbre B+. améliorant ainsi le débit global

Puissance de calcul-Serveur TiDB

Le serveur TiDB lui-même est sans état, ce qui signifie que lorsque la puissance de calcul devient un goulot d'étranglement, la machine peut être directement étendue, ce qui est transparent pour les utilisateurs. Théoriquement, il n'y a pas de limite supérieure au nombre de serveurs TiDB.

Installation et déploiement de l'environnement expérimental TiDB

[Remarque] : Ici, nous déployons d'abord un environnement expérimental pour une familiarisation rapide, et l'installation et le déploiement au niveau de la production seront introduits plus tard.

Simuler le déploiement d'un cluster d'environnement de production sur une seule machine

Demandez une instance hôte cloud Alibaba Cloud ECS comme environnement de déploiement et ressources préemptives. Choisissez simplement l'option bon marché. Cela ne coûte que quelques yuans par jour.

Vous pouvez prédéfinir le mot de passe root, puis utiliser l'adresse IP publique pour vous connecter à l'aide de xshell. S'il existe un serveur local, vous pouvez utiliser votre propre serveur existant.

Informations sur l'environnement de la machine :

[root@iZ0jlfl8zktqzyt15o1o16Z ~]# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# free -g
              total        used        free      shared  buff/cache   available
Mem:             30           0          29           0           0          30
Swap:             0           0           0
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# lscpu 
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 85
Model name:            Intel(R) Xeon(R) Platinum 8269CY CPU @ 2.50GHz

Installer le serveur MySQL-mariadb

Installez MySQL-mariadb-server pour vous connecter à la base de données TiDB et utilisez-le pour les tests ultérieurs

# yum安装
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# yum install mariadb* -y
# 启动服务和开机自启
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# systemctl start mariadb && systemctl enable mariadb
Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# 

[root@iZ0jlfl8zktqzyt15o1o16Z ~]# netstat -tnlpu|grep 3306
tcp6       0      0 :::3306                 :::*                    LISTEN      11576/mysqld        

[root@iZ0jlfl8zktqzyt15o1o16Z ~]# mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.5.68-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Root@123';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'USER 'root'@'localhost' IDENTIFIED BY 'Root@123'' at line 1
MariaDB [(none)]> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [mysql]> UPDATE user SET password=password('123456') WHERE user='root';
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4  Changed: 4  Warnings: 0
MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
MariaDB [mysql]> exit;
Bye
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> exit
Bye
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# 

Installer la version autonome

Simuler le déploiement d'un cluster d'environnement de production sur une seule machine

Scénario applicable : vous souhaitez utiliser un seul serveur Linux pour découvrir le plus petit cluster de topologie complet de TiDB et simuler les étapes de déploiement dans un environnement de production.

# 在单机上模拟部署生产环境集群
# 下载并安装 TiUP
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
WARN: adding root certificate via internet: https://tiup-mirrors.pingcap.com/root.json
You can revoke this by remove /root/.tiup/bin/7b8e153f2e2d0928.root.json
Successfully set mirror to https://tiup-mirrors.pingcap.com
Detected shell: bash
Shell profile:  /root/.bash_profile
/root/.bash_profile has been modified to add tiup to PATH
open a new terminal or source /root/.bash_profile to use it
Installed path: /root/.tiup/bin/tiup
===============================================
Have a try:     tiup playground
===============================================
# 根据提示source引入环境变量
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# source /root/.bash_profile
# 安装 TiUP 的 cluster 组件
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# tiup cluster
tiup is checking updates for component cluster ...
A new version of cluster is available:
   The latest version:         v1.10.3
   Local installed version:    
   Update current component:   tiup update cluster
   Update all components:      tiup update --all

The component `cluster` version  is not installed; downloading from repository.
download https://tiup-mirrors.pingcap.com/cluster-v1.10.3-linux-amd64.tar.gz 8.28 MiB / 8.28 MiB 100.00% 12.07 MiB/s                                               
Starting component `cluster`: /root/.tiup/components/cluster/v1.10.3/tiup-cluster
Deploy a TiDB cluster for production
# 根据提示信息需要update
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# tiup update --self && tiup update cluster
download https://tiup-mirrors.pingcap.com/tiup-v1.10.3-linux-amd64.tar.gz 6.81 MiB / 6.81 MiB 100.00% 12.83 MiB/s                                                  
Updated successfully!
component cluster version v1.10.3 is already installed
Updated successfully!
# 由于模拟多机部署,需要通过 root 用户调大 sshd 服务的连接数限制
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# cat /etc/ssh/sshd_config | grep MaxSessions
#MaxSessions 10
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# echo "MaxSessions 20" >> /etc/ssh/sshd_config
# 或者vim打开文件打开注释,把10改为20保存
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# cat /etc/ssh/sshd_config | grep MaxSessions|grep -vE "^#"
MaxSessions 20
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# service sshd restart
Redirecting to /bin/systemctl restart sshd.service
# 创建启动机器定义文件
#按下面的配置模板,编辑配置文件,命名为 topo.yaml,其中:
	#user: "tidb":表示通过 tidb 系统用户(部署会自动创建)来做集群的内部管理,默认使用 22 端口通过 ssh 登录目标机器
	#replication.enable-placement-rules:设置这个 PD 参数来确保 TiFlash 正常运行
	#host:设置为本部署主机的 IP
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# vi topo.yaml

# # Global variables are applied to all deployments and used as the default value of
# # the deployments if a specific deployment value is missing.
global:
 user: "tidb"
 ssh_port: 22
 deploy_dir: "/tidb-deploy"
 data_dir: "/tidb-data"

# # Monitored variables are applied to all the machines.
monitored:
 node_exporter_port: 9100
 blackbox_exporter_port: 9115

server_configs:
 tidb:
   log.slow-threshold: 300
 tikv:
   readpool.storage.use-unified-pool: false
   readpool.coprocessor.use-unified-pool: true
 pd:
   replication.enable-placement-rules: true
   replication.location-labels: ["host"]
 tiflash:
   logger.level: "info"

pd_servers:
 - host: 172.28.54.199

tidb_servers:
 - host: 172.28.54.199

tikv_servers:
 - host: 172.28.54.199
   port: 20160
   status_port: 20180
   config:
     server.labels: {
    
     host: "logic-host-1" }

 - host: 172.28.54.199
   port: 20161
   status_port: 20181
   config:
     server.labels: {
    
     host: "logic-host-2" }

 - host: 172.28.54.199
   port: 20162
   status_port: 20182
   config:
     server.labels: {
    
     host: "logic-host-3" }

tiflash_servers:
 - host: 172.28.54.199

monitoring_servers:
 - host: 172.28.54.199

grafana_servers:
 - host: 172.28.54.199

# 查看可以部署的版本信息
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# tiup list tidb

# tiup cluster deploy <cluster-name> <tidb-version> ./topo.yaml --user root -p
#参数 <cluster-name> 表示设置集群名称
#参数 <tidb-version> 表示设置集群版本,可以通过 tiup list tidb 命令来查看当前支持部署的 TiDB 版本
#参数 -p 表示在连接目标机器时使用密码登录
# 按照引导,输入”y”及 root 密码,来完成部署:
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# tiup cluster deploy wangtingtidb v5.2.4 ./topo.yaml --user root -p
tiup is checking updates for component cluster ...
Starting component `cluster`: /root/.tiup/components/cluster/v1.10.3/tiup-cluster deploy wangtingtidb v5.2.4 ./topo.yaml --user root -p
Input SSH password: 

+ Detect CPU Arch Name
  - Detecting node 172.28.54.199 Arch info ... Done

+ Detect CPU OS Name
  - Detecting node 172.28.54.199 OS info ... Done
Please confirm your topology:
Cluster type:    tidb
Cluster name:    wangtingtidb
Cluster version: v5.2.4
Role        Host           Ports                            OS/Arch       Directories
----        ----           -----                            -------       -----------
pd          172.28.54.199  2379/2380                        linux/x86_64  /tidb-deploy/pd-2379,/tidb-data/pd-2379
tikv        172.28.54.199  20160/20180                      linux/x86_64  /tidb-deploy/tikv-20160,/tidb-data/tikv-20160
tikv        172.28.54.199  20161/20181                      linux/x86_64  /tidb-deploy/tikv-20161,/tidb-data/tikv-20161
tikv        172.28.54.199  20162/20182                      linux/x86_64  /tidb-deploy/tikv-20162,/tidb-data/tikv-20162
tidb        172.28.54.199  4000/10080                       linux/x86_64  /tidb-deploy/tidb-4000
tiflash     172.28.54.199  9000/8123/3930/20170/20292/8234  linux/x86_64  /tidb-deploy/tiflash-9000,/tidb-data/tiflash-9000
prometheus  172.28.54.199  9090                             linux/x86_64  /tidb-deploy/prometheus-9090,/tidb-data/prometheus-9090
grafana     172.28.54.199  3000                             linux/x86_64  /tidb-deploy/grafana-3000
Attention:
    1. If the topology is not what you expected, check your yaml file.
    2. Please confirm there is no port/directory conflicts in same host.
Do you want to continue? [y/N]: (default=N) y
+ Generate SSH keys ... Done
+ Download TiDB components
  - Download pd:v5.2.4 (linux/amd64) ... Done
  - Download tikv:v5.2.4 (linux/amd64) ... Done
  - Download tidb:v5.2.4 (linux/amd64) ... Done
  - Download tiflash:v5.2.4 (linux/amd64) ... Done
  - Download prometheus:v5.2.4 (linux/amd64) ... Done
  - Download grafana:v5.2.4 (linux/amd64) ... Done
  - Download node_exporter: (linux/amd64) ... Done
  - Download blackbox_exporter: (linux/amd64) ... Done
+ Initialize target host environments
  - Prepare 172.28.54.199:22 ... Done
+ Deploy TiDB instance
  - Copy pd -> 172.28.54.199 ... Done
  - Copy tikv -> 172.28.54.199 ... Done
  - Copy tikv -> 172.28.54.199 ... Done
  - Copy tikv -> 172.28.54.199 ... Done
  - Copy tidb -> 172.28.54.199 ... Done
  - Copy tiflash -> 172.28.54.199 ... Done
  - Copy prometheus -> 172.28.54.199 ... Done
  - Copy grafana -> 172.28.54.199 ... Done
  - Deploy node_exporter -> 172.28.54.199 ... Done
  - Deploy blackbox_exporter -> 172.28.54.199 ... Done
+ Copy certificate to remote host
+ Init instance configs
  - Generate config pd -> 172.28.54.199:2379 ... Done
  - Generate config tikv -> 172.28.54.199:20160 ... Done
  - Generate config tikv -> 172.28.54.199:20161 ... Done
  - Generate config tikv -> 172.28.54.199:20162 ... Done
  - Generate config tidb -> 172.28.54.199:4000 ... Done
  - Generate config tiflash -> 172.28.54.199:9000 ... Done
  - Generate config prometheus -> 172.28.54.199:9090 ... Done
  - Generate config grafana -> 172.28.54.199:3000 ... Done
+ Init monitor configs
  - Generate config node_exporter -> 172.28.54.199 ... Done
  - Generate config blackbox_exporter -> 172.28.54.199 ... Done
+ Check status
Enabling component pd
	Enabling instance 172.28.54.199:2379
	Enable instance 172.28.54.199:2379 success
Enabling component tikv
	Enabling instance 172.28.54.199:20162
	Enabling instance 172.28.54.199:20160
	Enabling instance 172.28.54.199:20161
	Enable instance 172.28.54.199:20160 success
	Enable instance 172.28.54.199:20162 success
	Enable instance 172.28.54.199:20161 success
Enabling component tidb
	Enabling instance 172.28.54.199:4000
	Enable instance 172.28.54.199:4000 success
Enabling component tiflash
	Enabling instance 172.28.54.199:9000
	Enable instance 172.28.54.199:9000 success
Enabling component prometheus
	Enabling instance 172.28.54.199:9090
	Enable instance 172.28.54.199:9090 success
Enabling component grafana
	Enabling instance 172.28.54.199:3000
	Enable instance 172.28.54.199:3000 success
Enabling component node_exporter
	Enabling instance 172.28.54.199
	Enable 172.28.54.199 success
Enabling component blackbox_exporter
	Enabling instance 172.28.54.199
	Enable 172.28.54.199 success
Cluster `wangtingtidb` deployed successfully, you can start it with command: `tiup cluster start wangtingtidb --init`

# 根据提示命令tiup cluster start wangtingtidb --init启动集群
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# tiup cluster start wangtingtidb --init
tiup is checking updates for component cluster ...
Starting component `cluster`: /root/.tiup/components/cluster/v1.10.3/tiup-cluster start wangtingtidb --init
Starting cluster wangtingtidb...
+ [ Serial ] - SSHKeySet: privateKey=/root/.tiup/storage/cluster/clusters/wangtingtidb/ssh/id_rsa, publicKey=/root/.tiup/storage/cluster/clusters/wangtingtidb/ssh/id_rsa.pub
+ [Parallel] - UserSSH: user=tidb, host=172.28.54.199
+ [Parallel] - UserSSH: user=tidb, host=172.28.54.199
+ [Parallel] - UserSSH: user=tidb, host=172.28.54.199
+ [Parallel] - UserSSH: user=tidb, host=172.28.54.199
+ [Parallel] - UserSSH: user=tidb, host=172.28.54.199
+ [Parallel] - UserSSH: user=tidb, host=172.28.54.199
+ [Parallel] - UserSSH: user=tidb, host=172.28.54.199
+ [Parallel] - UserSSH: user=tidb, host=172.28.54.199
+ [ Serial ] - StartCluster
Starting component pd
	Starting instance 172.28.54.199:2379
	Start instance 172.28.54.199:2379 success
Starting component tikv
	Starting instance 172.28.54.199:20162
	Starting instance 172.28.54.199:20160
	Starting instance 172.28.54.199:20161
	Start instance 172.28.54.199:20160 success
	Start instance 172.28.54.199:20161 success
	Start instance 172.28.54.199:20162 success
Starting component tidb
	Starting instance 172.28.54.199:4000
	Start instance 172.28.54.199:4000 success
Starting component tiflash
	Starting instance 172.28.54.199:9000
	Start instance 172.28.54.199:9000 success
Starting component prometheus
	Starting instance 172.28.54.199:9090
	Start instance 172.28.54.199:9090 success
Starting component grafana
	Starting instance 172.28.54.199:3000
	Start instance 172.28.54.199:3000 success
Starting component node_exporter
	Starting instance 172.28.54.199
	Start 172.28.54.199 success
Starting component blackbox_exporter
	Starting instance 172.28.54.199
	Start 172.28.54.199 success
+ [ Serial ] - UpdateTopology: cluster=wangtingtidb
Started cluster `wangtingtidb` successfully
The root password of TiDB database has been changed.
The new password is: 'rpi381$9*!cvX07D-w'.
Copy and record it to somewhere safe, it is only displayed once, and will not be stored.
The generated password can NOT be get and shown again.
# 注意TiDB的初始密码会控制台输出,拷贝留存一份
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# 
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# mysql -h 172.28.54.199 -P 4000 -u root -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 5.7.25-TiDB-v5.2.4 TiDB Server (Apache License 2.0) Community Edition, MySQL 5.7 compatible

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MySQL [mysql]> Set password for 'root'@'%'=password('123456');
Query OK, 0 rows affected (0.02 sec)

MySQL [mysql]> flush privileges;
Query OK, 0 rows affected (0.01 sec)

MySQL [mysql]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
Query OK, 0 rows affected (0.02 sec)

MySQL [mysql]> exit;
Bye

Vérifier le cluster

# 执行以下命令确认当前已经部署的集群列表:
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# tiup cluster list
tiup is checking updates for component cluster ...
Starting component `cluster`: /root/.tiup/components/cluster/v1.10.3/tiup-cluster list
Name          User  Version  Path                                               PrivateKey
----          ----  -------  ----                                               ----------
wangtingtidb  tidb  v5.2.4   /root/.tiup/storage/cluster/clusters/wangtingtidb  /root/.tiup/storage/cluster/clusters/wangtingtidb/ssh/id_rsa

# 执行以下命令查看集群的拓扑结构和状态:
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# tiup cluster display wangtingtidb
tiup is checking updates for component cluster ...
Starting component `cluster`: /root/.tiup/components/cluster/v1.10.3/tiup-cluster display wangtingtidb
Cluster type:       tidb
Cluster name:       wangtingtidb
Cluster version:    v5.2.4
Deploy user:        tidb
SSH type:           builtin
Dashboard URL:      http://172.28.54.199:2379/dashboard
Grafana URL:        http://172.28.54.199:3000
ID                   Role        Host           Ports                            OS/Arch       Status   Data Dir                    Deploy Dir
--                   ----        ----           -----                            -------       ------   --------                    ----------
172.28.54.199:3000   grafana     172.28.54.199  3000                             linux/x86_64  Up       -                           /tidb-deploy/grafana-3000
172.28.54.199:2379   pd          172.28.54.199  2379/2380                        linux/x86_64  Up|L|UI  /tidb-data/pd-2379          /tidb-deploy/pd-2379
172.28.54.199:9090   prometheus  172.28.54.199  9090                             linux/x86_64  Up       /tidb-data/prometheus-9090  /tidb-deploy/prometheus-9090
172.28.54.199:4000   tidb        172.28.54.199  4000/10080                       linux/x86_64  Up       -                           /tidb-deploy/tidb-4000
172.28.54.199:9000   tiflash     172.28.54.199  9000/8123/3930/20170/20292/8234  linux/x86_64  Up       /tidb-data/tiflash-9000     /tidb-deploy/tiflash-9000
172.28.54.199:20160  tikv        172.28.54.199  20160/20180                      linux/x86_64  Up       /tidb-data/tikv-20160       /tidb-deploy/tikv-20160
172.28.54.199:20161  tikv        172.28.54.199  20161/20181                      linux/x86_64  Up       /tidb-data/tikv-20161       /tidb-deploy/tikv-20161
172.28.54.199:20162  tikv        172.28.54.199  20162/20182                      linux/x86_64  Up       /tidb-data/tikv-20162       /tidb-deploy/tikv-20162
Total nodes: 8

Accédez à la surveillance Grafana de TiDB :
accédez à la page de surveillance Grafana du cluster via http://39.101.65.150:3000. Le nom d'utilisateur et le mot de passe par défaut sont tous deux admin.
Vous devez changer le mot de passe initial pour la première visite en 123456

Visitez le tableau de bord de TiDB :

Accédez à la page de surveillance du tableau de bord TiDB du cluster via http://39.101.65.150:2379/dashboard. Le nom d'utilisateur par défaut est root et le mot de passe est 123456 nouvellement défini dans MySQL.

# 命令行在mariadb和TiDB分别建库
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# mysql -u root -P 3306 -h 39.101.65.150 -p"123456" -e "create database mariadb_666;"
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# mysql -u root -P 4000 -h 39.101.65.150 -p"123456" -e "create database tidb_666;"

Vous pouvez voir qu'il a été vu dans les deux bases de données

Introduction à l'utilisation de TiDB

Opérations SQL

[root@iZ0jlfl8zktqzyt15o1o16Z ~]# mysql -u root -P 4000 -h 39.101.65.150 -p"123456"
Welcome to the MariaDB monitor.  Commands end with ; or \g.
# 创建一个名为 samp_db 的数据库
MySQL [(none)]> CREATE DATABASE IF NOT EXISTS samp_db;
Query OK, 0 rows affected (0.08 sec)
# 查看数据库
MySQL [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| INFORMATION_SCHEMA |
| METRICS_SCHEMA     |
| PERFORMANCE_SCHEMA |
| mysql              |
| samp_db            |
| test               |
| tidb_666           |
+--------------------+
7 rows in set (0.01 sec)
# 删除数据库
MySQL [(none)]> DROP DATABASE samp_db;
Query OK, 0 rows affected (0.19 sec)

MySQL [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| INFORMATION_SCHEMA |
| METRICS_SCHEMA     |
| PERFORMANCE_SCHEMA |
| mysql              |
| test               |
| tidb_666           |
+--------------------+
6 rows in set (0.01 sec)

MySQL [(none)]> CREATE DATABASE IF NOT EXISTS samp_db;
Query OK, 0 rows affected (0.08 sec)
# 切换数据库
MySQL [(none)]> USE samp_db;
Database changed
# 创建表
MySQL [samp_db]> CREATE TABLE IF NOT EXISTS person (
    ->       number INT(11),
    ->       name VARCHAR(255),
    ->       birthday DATE
    -> );
Query OK, 0 rows affected (0.08 sec)
# 查看建表语句
MySQL [samp_db]> SHOW CREATE table person;
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table                                                                                                                                                                            |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| person | CREATE TABLE `person` (
  `number` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `birthday` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
# 查看表的列
MySQL [samp_db]> SHOW FULL COLUMNS FROM person;
+----------+--------------+-------------+------+------+---------+-------+---------------------------------+---------+
| Field    | Type         | Collation   | Null | Key  | Default | Extra | Privileges                      | Comment |
+----------+--------------+-------------+------+------+---------+-------+---------------------------------+---------+
| number   | int(11)      | NULL        | YES  |      | NULL    |       | select,insert,update,references |         |
| name     | varchar(255) | utf8mb4_bin | YES  |      | NULL    |       | select,insert,update,references |         |
| birthday | date         | NULL        | YES  |      | NULL    |       | select,insert,update,references |         |
+----------+--------------+-------------+------+------+---------+-------+---------------------------------+---------+
3 rows in set (0.00 sec)

MySQL [samp_db]> DROP TABLE IF EXISTS person;
Query OK, 0 rows affected (0.20 sec)

MySQL [samp_db]> CREATE TABLE IF NOT EXISTS person (
    ->       number INT(11),
    ->       name VARCHAR(255),
    ->       birthday DATE
    -> );
Query OK, 0 rows affected (0.08 sec)
# 创建索引,对于值不唯一的列,可使用 CREATE INDEX 或 ALTER TABLE 语句
MySQL [samp_db]> CREATE INDEX person_num ON person (number);
Query OK, 0 rows affected (2.76 sec)
# 查看表内所有索引
MySQL [samp_db]> SHOW INDEX from person;
+--------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+-----------+
| Table  | Non_unique | Key_name   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression | Clustered |
+--------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+-----------+
| person |          1 | person_num |            1 | number      | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               | YES     | NULL       | NO        |
+--------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+-----------+
1 row in set (0.01 sec)
# 删除索引
MySQL [samp_db]> DROP INDEX person_num ON person;
Query OK, 0 rows affected (0.26 sec)
# 创建唯一索引
MySQL [samp_db]> CREATE UNIQUE INDEX person_num ON person (number);
Query OK, 0 rows affected (2.76 sec)
# 插入数据
MySQL [samp_db]> INSERT INTO person VALUES("1","tom","20170912");
Query OK, 1 row affected (0.01 sec)
# 查数据
MySQL [samp_db]> SELECT * FROM person;
+--------+------+------------+
| number | name | birthday   |
+--------+------+------------+
|      1 | tom  | 2017-09-12 |
+--------+------+------------+
1 row in set (0.01 sec)
# 修改表内数据
MySQL [samp_db]> UPDATE person SET birthday='20200202' WHERE name='tom';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MySQL [samp_db]> SELECT * FROM person;
+--------+------+------------+
| number | name | birthday   |
+--------+------+------------+
|      1 | tom  | 2020-02-02 |
+--------+------+------------+
1 row in set (0.00 sec)
# 删除表内数据
MySQL [samp_db]> DELETE FROM person WHERE number=1;
Query OK, 1 row affected (0.01 sec)

MySQL [samp_db]> SELECT * FROM person;
Empty set (0.01 sec)
# 创建一个用户 tiuser,登录为本地localhost访问
MySQL [samp_db]> CREATE USER 'tiuser'@'localhost' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.02 sec)
# 本地验证
[root@iZ0jlfl8zktqzyt15o1o16Z ~]# mysql -u tiuser  -P 4000 -h 127.0.0.1 -p"123456"
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 99
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| INFORMATION_SCHEMA |
+--------------------+
1 row in set (0.00 sec)
MySQL [(none)]> 

Impossible d'accéder à distance

Autorisez les utilisateurs ordinaires à accéder à distance :

MySQL [mysql]> update user set host='%' where user='tiuser';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0
MySQL [mysql]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

Autorisez les utilisateurs ordinaires à accéder à la bibliothèque :

MySQL [mysql]> GRANT SELECT ON samp_db.* TO 'tiuser'@'%';
Query OK, 0 rows affected (0.01 sec)
MySQL [mysql]> SHOW GRANTS for 'tiuser'@'%';
+-------------------------------------------+
| Grants for tiuser@%                       |
+-------------------------------------------+
| GRANT USAGE ON *.* TO 'tiuser'@'%'        |
| GRANT SELECT ON samp_db.* TO 'tiuser'@'%' |
+-------------------------------------------+
2 rows in set (0.00 sec)

supprimer des utilisateurs

# 删除用户 tiuser
MySQL [samp_db]> DROP USER 'tiuser'@'localhost';
Query OK, 0 rows affected (0.03 sec)
# 查看所有权限
MySQL [samp_db]> SHOW GRANTS;
+-------------------------------------------------------------+
| Grants for User                                             |
+-------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION |
+-------------------------------------------------------------+
1 row in set (0.00 sec)
MySQL [samp_db]> 

Lire les données historiques

Description de la fonction

TiDB implémente la fonction de lecture des données historiques via l'interface SQL standard, sans avoir besoin d'un client ou d'un pilote spécial. Une fois les données mises à jour ou supprimées, les données avant la mise à jour/suppression peuvent toujours être lues via l'interface SQL.

De plus, même si la structure de la table change après la mise à jour des données, TiDB peut toujours lire les données en utilisant l'ancienne structure de la table.

Procédures opérationnelles

​Pour prendre en charge la lecture des données de version historique, une nouvelle variable système est introduite : tidb_snapshot. Cette variable est valide dans la portée Session et sa valeur peut être modifiée via l'instruction Set standard. Sa valeur est du texte et peut stocker TSO et datetime. TSO est l'horodatage global, obtenu du côté PD ; le format de la date et de l'heure peut être : "2020-10-08 16:45:26.999". De manière générale, il ne peut être écrit qu'en secondes, comme " 2020-10-08 16:45:26". Lorsque cette variable est définie, TiDB utilisera cet horodatage pour créer un instantané (pas de surcharge, créez simplement une structure de données), et toutes les opérations de sélection ultérieures liront les données sur cet instantané.
Remarque :
les transactions TiDB sont globalement chronométrées via PD, de sorte que la version des données stockées utilise également l'horodatage accordé par PD comme numéro de version. Lors de la génération d'un Snapshot, la valeur de la variable tidb_snapshot est utilisée comme numéro de version. Si l'heure locale de la machine sur laquelle se trouve le serveur TiDB et la machine sur laquelle se trouve le serveur PD sont significativement différentes, l'heure du PD a besoin pour prévaloir.
​ Lorsque l'opération de lecture de la version historique est terminée, vous pouvez mettre fin à la session en cours ou définir la valeur de la variable tidb_snapshot sur "" via l'instruction Set pour lire la dernière version des données.

Politique de conservation des données historiques

​ TiDB utilise MVCC pour gérer les versions. Lors de la mise à jour/suppression de données, aucune suppression réelle de données ne sera effectuée, seule une nouvelle version des données sera ajoutée, afin que les données historiques puissent être conservées. Toutes les données historiques ne seront pas conservées. Les données historiques qui dépassent une certaine période de temps seront complètement supprimées pour réduire l'utilisation de l'espace et éviter la surcharge de performances causée par un trop grand nombre de versions historiques.
TiDB utilise GC (Garbage Collection) qui s'exécute périodiquement pour le nettoyage. Pour plus de détails sur GC, voir TiDB Garbage Collection (GC).
​ Ce sur quoi il faut se concentrer ici, ce sont tikv_gc_life_time et tikv_gc_safe_point. tikv_gc_life_time est utilisé pour configurer le temps de conservation des versions historiques et peut être modifié manuellement ; tikv_gc_safe_point enregistre le SafePoint actuel et les utilisateurs peuvent utiliser en toute sécurité un horodatage supérieur à SafePoint pour créer des instantanés et lire les versions historiques. safePoint est automatiquement mis à jour à chaque fois que GC démarre

Exemple d'opération de lecture de données historiques

# 创建一个表,并插入几行测试数据
MySQL [mysql]> create table t (c int);
Query OK, 0 rows affected (0.08 sec)

MySQL [mysql]> insert into t values (1), (2), (3);
Query OK, 3 rows affected (0.04 sec)
Records: 3  Duplicates: 0  Warnings: 0
# 查看表中的数据
MySQL [mysql]> select * from t;
+------+
| c    |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

# 查看当前时间,一般这个时间可以理解成数据的版本和时间挂钩,在某个时间点前和后有变动,查询时可以以时间为参照点
MySQL [mysql]> select now();
+---------------------+
| now()               |
+---------------------+
| 2022-08-22 10:17:26 |
+---------------------+
1 row in set (0.01 sec)
# 更新某一行数据
MySQL [mysql]> update t set c=222222 where c=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MySQL [mysql]> select * from t;
+--------+
| c      |
+--------+
|      1 |
| 222222 |
|      3 |
+--------+
3 rows in set (0.00 sec)
# 设置一个特殊的环境变量,这个是一个 session scope 的变量,其意义为读取这个时间之前的最新的一个版本,也就时查询数据时不再是实时数据,而是截至到2022-08-22 10:17:26时间的数据,这个时间之后的数据修改不体现,从而实现查询历史数据
MySQL [mysql]> set @@tidb_snapshot="2022-08-22 10:17:26";
Query OK, 0 rows affected (0.00 sec)
#注意:
#这里的时间设置的是 update 语句之前的那个时间。
#在 tidb_snapshot 前须使用 @@ 而非 @,因为 @@ 表示系统变量,@ 表示用户变量
MySQL [mysql]> select * from t;
+------+
| c    |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)
# 清空这个变量后,即可读取最新版本数据
MySQL [mysql]> set @@tidb_snapshot="";
Query OK, 0 rows affected (0.00 sec)

MySQL [mysql]> select * from t;
+--------+
| c      |
+--------+
|      1 |
| 222222 |
|      3 |
+--------+
3 rows in set (0.00 sec)

Principe de la technologie TiDB

La base de données, le système d'exploitation et le compilateur sont collectivement appelés les trois principaux systèmes, qui peuvent être considérés comme la pierre angulaire de l'ensemble du logiciel informatique. La base de données est plus proche de la couche application et supporte de nombreuses entreprises. Après des décennies de développement, ce domaine continue de progresser.

De nombreuses personnes ont utilisé des bases de données, mais peu ont implémenté une base de données, notamment une base de données distribuée. Comprendre les principes de mise en œuvre et les détails de la base de données peut, d'une part, améliorer les compétences personnelles et aider à construire d'autres systèmes, et d'autre part, cela peut également aider à faire bon usage de la base de données.

La meilleure façon d’étudier une technologie est d’étudier l’un des projets open source, et les bases de données ne font pas exception. Il existe de nombreux bons projets open source dans le domaine des bases de données autonomes, parmi lesquels MySQL et PostgreSQL sont les deux plus connus. De nombreux étudiants ont vu les codes de ces deux projets. Mais en termes de bases de données distribuées, il n’existe pas beaucoup de bons projets open source. TiDB suscite actuellement une large attention, notamment de la part de certains passionnés de technologie qui espèrent participer à ce projet. En raison de la complexité de la base de données distribuée elle-même, beaucoup de gens ne comprennent pas bien l'ensemble du projet, j'espère donc écrire quelques articles, de haut en bas, de superficiel en profondeur, sur certains des principes techniques de TiDB, y compris l'utilisation. des technologies visibles et un grand nombre de points techniques cachés derrière l'interface SQL et invisibles pour les utilisateurs

stockage de données

La fonction la plus fondamentale d’une base de données est de sauvegarder les données, nous commençons donc ici.

Il existe de nombreuses façons de sauvegarder des données, la méthode la plus simple consiste à créer une structure de données directement dans la mémoire pour sauvegarder les données envoyées par l'utilisateur. Par exemple, en utilisant un tableau, chaque fois qu'une donnée est reçue, un enregistrement est ajouté au tableau. Cette solution est très simple, peut répondre aux exigences les plus élémentaires et les performances seront certainement très bonnes, mais à part cela, elle est pleine de failles. Le plus gros problème est que les données sont entièrement en mémoire. Une fois le service lancé arrêté ou le service est redémarré, les données seront définitivement perdues.

Afin de résoudre le problème de la perte de données, nous pouvons placer les données sur un support de stockage non volatil (tel qu'un disque dur). La solution améliorée consiste à créer un fichier sur le disque et, lorsqu'une donnée est reçue, à ajouter une ligne dans le fichier. OK, nous avons maintenant une solution pour stocker des données de manière persistante. Mais ce n’est pas suffisant : que se passe-t-il si le disque présente des secteurs défectueux ? Nous pouvons faire du RAID (Redundant Array of Independent Disks) pour fournir un stockage redondant autonome. Que se passe-t-il si la machine entière se bloque ? Par exemple, en cas d'incendie, le RAID ne peut pas protéger les données. Nous pouvons également basculer le stockage vers le stockage réseau ou effectuer une réplication du stockage via du matériel ou des logiciels. À ce stade, il semble que nous ayons résolu le problème de la sécurité des données et que nous puissions pousser un soupir de soulagement. Mais la cohérence entre les copies peut-elle être garantie pendant le processus de copie ? C'est-à-dire que, sous réserve de garantir que les données ne soient pas perdues, il faut également s'assurer que les données sont bonnes. Veiller à ce que les données ne soient pas perdues n'est que l'exigence la plus élémentaire, et il y a encore d'autres problèmes qui attendent d'être résolus :

• Peut-il prendre en charge la reprise après sinistre dans les centres de données ?

• La vitesse d'écriture est-elle suffisamment rapide ?

• Une fois les données enregistrées, sont-elles faciles à lire ?

• Comment modifier les données enregistrées ? Comment prendre en charge les modifications simultanées ?

• Comment modifier plusieurs enregistrements de manière atomique ?

Chacun de ces problèmes est très difficile, mais pour créer un excellent système de stockage de données, chacun des problèmes ci-dessus doit être résolu. Afin de résoudre le problème du stockage des données, nous avons développé le projet TiKV. Ensuite, je vais vous présenter quelques idées de conception et concepts de base de TiKV.

Valeur clé

En tant que système de sauvegarde de données, la première chose à décider est le modèle de stockage des données, c'est-à-dire sous quelle forme les données seront enregistrées. Le choix de TiKV se porte sur le modèle Key-Value et fournit une méthode de parcours ordonné. Pour faire simple, TiKV peut être considéré comme une immense carte, dans laquelle la clé et la valeur sont des tableaux d'octets originaux. Dans cette carte, les clés sont disposées dans l'ordre de comparaison du total des bits binaires originaux du tableau d'octets.

  1. Il s'agit d'une énorme carte qui stocke les paires clé-valeur.

  2. Les paires clé-valeur dans cette carte sont classées selon l'ordre binaire de la clé, c'est-à-dire que nous pouvons rechercher l'emplacement d'une certaine clé, puis appeler en continu la méthode Next pour obtenir des valeurs-clés plus grandes que celle-ci. Clé par ordre croissant.

Oublions maintenant tous les concepts de SQL et concentrons-nous sur la façon d'implémenter une énorme carte (distribuée) hautes performances et haute fiabilité comme TiKV.

RochesDB

​ Pour tout moteur de stockage persistant, les données doivent être enregistrées sur disque, et TiKV ne fait pas exception. Cependant, TiKV ne choisit pas d'écrire les données directement sur le disque, mais enregistre les données dans RocksDB, et RocksDB est responsable de l'implémentation spécifique des données. La raison de ce choix est qu'il faut beaucoup de travail pour développer un moteur de stockage autonome, en particulier pour construire un moteur autonome hautes performances, qui nécessite diverses optimisations détaillées. RocksDB est un très excellent moteur autonome open source. moteur de stockage qui peut satisfaire nos besoins. Il existe diverses exigences pour le moteur autonome, et l'équipe Facebook effectue une optimisation continue, afin que nous puissions profiter d'un moteur autonome très puissant et en constante amélioration avec seulement un petit investissement d'énergie . Bien sûr, nous avons également contribué du code à RocksDB et espérons que ce projet s'améliorera de plus en plus. Ici, vous pouvez simplement considérer RocksDB comme une carte clé-valeur autonome.

L'arborescence LSM sous-jacente stocke les modifications incrémentielles des données dans la mémoire. Après avoir atteint la limite de taille spécifiée, les données sont vidées sur le disque par lots. Les arborescences du disque peuvent être fusionnées périodiquement pour fusionner en une seule grande arborescence afin d'optimiser les performances. .

Radeau

​ Comment garantir que les données ne seront pas perdues ou que des erreurs ne se produiront pas en cas de panne d'une seule machine ? Pour faire simple, nous devons trouver un moyen de copier les données sur plusieurs machines, de sorte que si une machine tombe en panne, nous ayons toujours des copies sur d'autres machines ; de manière plus complexe, nous avons également besoin que cette solution de réplication soit fiable, efficace et performante. . Gérer les situations d'échec de réplication. Cela semble difficile, mais heureusement nous disposons du protocole Raft. Raft est un algorithme de consensus équivalent à Paxos mais plus facile à comprendre. Si vous êtes intéressé, vous pouvez lire l’article de Raft. Cet article ne donnera qu'une brève introduction à Raft. Pour plus de détails, veuillez vous référer au document. Un autre point à mentionner est que le papier Raft n'est qu'une solution de base. S'il est implémenté strictement selon le papier, les performances seront très mauvaises. Nous avons apporté de nombreuses optimisations à la mise en œuvre du protocole Raft. Pour une optimisation spécifique Pour plus de détails, veuillez vous référer à l'optimisation « TiKV Source Code Analysis Series-Raft » de Tangliu dans cet article.
Raft est un protocole de cohérence qui fournit plusieurs fonctions importantes :
1. Élection du leader
2. Changement de membre
3. Réplication des journaux
TiKV utilise Raft pour la réplication des données. Chaque modification de données sera enregistrée sous forme de journal Raft. Grâce à la fonction de réplication des journaux de Raft pour synchroniser les données avec la plupart des nœuds du Groupe de manière sûre et fiable

​ Grâce à RocksDB autonome, nous pouvons stocker rapidement des données sur disque ; grâce à Raft, nous pouvons copier des données sur plusieurs machines pour éviter une panne d'une seule machine. Les données sont écrites via l'interface de la couche Raft au lieu d'être écrites directement dans RocksDB. En implémentant Raft, nous avons un KV distribué, et maintenant nous n'avons plus à nous soucier du crash d'une certaine machine.

Région

​ En parlant de cela, nous pouvons évoquer un concept très important : la Région. Ce concept constitue la base de la compréhension des séries de mécanismes suivantes. Veuillez lire attentivement cette section.
​Comme mentionné précédemment, nous considérons TiKV comme une énorme carte KV ordonnée. Par conséquent, afin de réaliser une expansion horizontale du stockage, nous devons distribuer les données sur plusieurs machines. Les données mentionnées ici sont dispersées sur plusieurs machines et la réplication des données de Raft n'est pas un concept. Dans cette section, nous oublions Raft et supposons que toutes les données n'ont qu'une seule copie, ce qui est plus facile à comprendre.
​ Pour un système KV, il existe deux solutions typiques pour disperser les données sur plusieurs machines : l'une consiste à hacher en fonction de la clé et à sélectionner le nœud de stockage correspondant en fonction de la valeur de hachage ; l'autre consiste à diviser la plage et une certaine période de continuité Les clés sont toutes stockées sur un nœud de stockage. TiKV a choisi la deuxième méthode, divisant l'ensemble de l'espace clé-valeur en plusieurs segments. Chaque segment est une série de clés consécutives. Nous appelons chaque segment une région et nous essaierons de conserver les données stockées dans chaque région ne dépassant pas une certaine quantité. .La taille (cette taille est configurable, actuellement la valeur par défaut est de 64 Mo). Chaque région peut être décrite par un intervalle fermé à gauche et ouvert à droite de StartKey à EndKey.

Notez que la Région ici n'a toujours rien à voir avec la table en SQL ! S'il vous plaît, continuez à oublier SQL et ne parlez que de KV. Après avoir divisé les données en régions, nous ferons deux choses importantes :

  • En utilisant la région comme unité, répartissez les données sur tous les nœuds du cluster et essayez de vous assurer que le nombre de régions servies sur chaque nœud est à peu près le même.
  • Effectuer la réplication Raft et la gestion des membres en fonction de la région

Regardons d'abord le premier point. Les données sont divisées en plusieurs régions selon la clé, et les données de chaque région ne seront enregistrées que sur un seul nœud. Notre système aura un composant chargé de répartir les régions aussi uniformément que possible sur tous les nœuds du cluster. Cela permettra d'obtenir une expansion horizontale de la capacité de stockage d'une part (après l'ajout de nouveaux nœuds, les régions des autres nœuds seront automatiquement planifiées), d'un autre côté, l'équilibrage de charge est également obtenu (il n'y aura pas de situation où un certain nœud aura beaucoup de données et d'autres nœuds en auront peu). Dans le même temps, afin de garantir que le client de couche supérieure puisse accéder aux données requises, notre système disposera également d'un composant permettant d'enregistrer la répartition des régions sur les nœuds. Autrement dit, via n'importe quelle clé, vous pourrez interroger quelle région la clé se trouve et le nœud sur lequel se trouve actuellement la région.
​ Concernant le deuxième point, TiKV réplique les données en unités de région, c'est-à-dire que les données d'une région enregistreront plusieurs copies. Nous appelons chaque copie une réplique. Raft est utilisé pour maintenir la cohérence des données entre les répliques. Plusieurs répliques d'une région seront stockées sur différents nœuds pour former un groupe Raft. L'une des répliques servira de leader de ce groupe et l'autre réplique servira de suiveur. Toutes les lectures et écritures sont effectuées via le leader, puis copiées du leader vers les suiveurs.

​ Nous utilisons la région comme une unité pour disperser et répliquer les données, et nous disposons d'un système KeyValue distribué avec certaines capacités de reprise après sinistre. Nous n'avons plus à nous soucier de l'impossibilité de stocker les données ou de leur perte en raison d'une panne de disque. C'est cool, mais ce n'est pas encore parfait et nous avons besoin de plus de fonctionnalités.

MVCC

De nombreuses bases de données implémentent le contrôle multi-version (MVCC) et TiKV ne fait pas exception. Imaginez un scénario dans lequel deux clients modifient la valeur d'une clé en même temps. Sans MVCC, les données doivent être verrouillées. Dans un scénario distribué, cela peut entraîner des problèmes de performances et de blocage. L'implémentation MVCC de TiKV est implémentée en ajoutant la version après la clé. En termes simples, avant MVCC, TiKV peut être considéré comme ceci :

​ Clé1 -> Valeur
​ Clé2 -> Valeur
​ ……
​ CléN -> Valeur

Avec MVCC, la disposition des clés de TiKV est la suivante :

​ Clé1-Version3 -> Valeur
​ Clé1-Version2 -> Valeur
​ Clé1-Version1 -> Valeur
​ ……
​ Clé2-Version4 -> Valeur
​ Clé2
-Version3 -> Valeur​ Clé2-Version2 -> Valeur
​ Clé2-Version1 - > Valeur
​ ……
​ KeyN-Version2 -> Valeur
​ KeyN-Version1 -> Valeur
​ ……

Notez que pour plusieurs versions de la même clé, nous mettons celle avec un numéro de version plus grand devant et celle avec un numéro de version plus petit à l'arrière (rappelez-vous que les clés que nous avons introduites dans la section Clé-Valeur sont disposées de manière ordonnée. manière), donc lorsque l'utilisateur obtient la valeur via une clé + version, la clé et la version peuvent être utilisées pour construire la clé MVCC, qui est Key-Version. Ensuite, vous pouvez directement rechercher (Key-Version) et localiser la première position supérieure ou égale à cette Key-Version.

affaires

Les transactions de TiKV utilisent le modèle Percolator et ont apporté de nombreuses optimisations. Les transactions de TiKV utilisent le verrouillage optimiste. Lors de l'exécution de la transaction, les conflits d'écriture-écriture ne seront pas détectés. La détection des conflits ne sera effectuée que pendant le processus de soumission. Les parties en conflit qui ont terminé la soumission plus tôt écriront avec succès et l'autre partie essayez de réexécuter la totalité de la transaction. Ce modèle fonctionne très bien lorsque les conflits d'écriture métier ne sont pas graves, comme la mise à jour aléatoire des données dans une certaine ligne d'une table et que la table est très volumineuse. Cependant, si le conflit d'écriture de l'entreprise est grave, les performances seront très mauvaises. Un exemple extrême est le compteur. Plusieurs clients modifient un petit nombre de lignes en même temps, ce qui entraîne de graves conflits et un grand nombre de tentatives invalides. .

Calcul des données

Mappage du modèle relationnel au modèle clé-valeur

​ Ici, nous comprenons simplement le modèle relationnel comme une table et des instructions SQL, la question devient alors de savoir comment enregistrer la table sur la structure KV et comment exécuter l'instruction SQL sur la structure KV. Supposons que nous ayons une telle définition de table :
CREATE TABLE User { ​ ID int,​ Name varchar(20),​ Role varchar(20),​ Age int,​ PRIMARY KEY (ID),​ Key idxAge (age) } ; Là Il y a une énorme différence entre les structures SQL et KV, donc comment les mapper de manière pratique et efficace est devenu une question très importante. Un bon schéma de cartographie doit répondre aux besoins des opérations sur les données. Voyons donc d’abord quelles sont les exigences relatives aux opérations de données et quelles sont leurs caractéristiques. Pour une table, les données qui doivent être stockées comprennent trois parties : 1. Méta-informations de la table 2. Ligne du tableau 3. Données d'index Nous ne discuterons pas des méta-informations de la table pour l'instant, mais nous les présenterons plus tard. . Pour Row, vous pouvez choisir le stockage en ligne ou le stockage en colonne, qui présentent tous deux leurs propres avantages et inconvénients. La cible principale de TiDB est l'activité OLTP. Ce type d'entreprise doit prendre en charge la lecture, l'enregistrement, la modification et la suppression rapides d'une ligne de données, il est donc plus approprié d'utiliser le stockage par ligne. Pour l'index, TiDB doit prendre en charge non seulement l'index primaire, mais également l'index secondaire. L'index fonctionne comme une requête auxiliaire, améliore les performances des requêtes et garantit certaines contraintes.















Il existe deux modes d'interrogation, l'un est une requête ponctuelle, telle que l'interrogation via des conditions équivalentes de clé primaire ou de clé unique, telles que la sélection du nom de l'utilisateur où id=1 ; Cela nécessite de localiser rapidement une certaine ligne de données via l'index ; L'autre est la requête Range, telle que sélectionner le nom de l'utilisateur où âge > 30 et âge < 35 ;. À ce stade, vous devez interroger les données dont l'âge est compris entre 30 et 35 via l'index idxAge. L'index est également divisé en index unique et index non unique, qui doivent tous deux être pris en charge.
Après avoir analysé les caractéristiques des données qui doivent être stockées, examinons les exigences opérationnelles de ces données, en considérant principalement les quatre instructions Insert/Update/Delete/Select.
Pour l'instruction Insert, Row doit être écrite dans KV et les données d'index doivent être établies.
Pour l'instruction Update, vous devez mettre à jour la ligne et en même temps mettre à jour les données d'index (si nécessaire).
Pour l'instruction Supprimer, l'index doit être supprimé lors de la suppression de la ligne.
Les trois déclarations ci-dessus sont très simples à traiter. Pour les instructions Select, la situation est un peu plus compliquée. Tout d'abord, nous devons pouvoir lire une ligne de données facilement et rapidement, chaque ligne doit donc avoir un identifiant (ID explicite ou implicite). Deuxièmement, plusieurs lignes consécutives de données peuvent être lues, telles que Select * from user ;. Enfin, il est nécessaire de lire les données via des index. L'utilisation d'index peut être des requêtes ponctuelles ou des requêtes par plage.
Les exigences générales ont été analysées, voyons maintenant ce qui est disponible : un moteur clé-valeur distribué globalement ordonné. L’ordre général est important et peut nous aider à résoudre de nombreux problèmes. Par exemple, pour obtenir rapidement une ligne de données, en supposant que l'on puisse construire une ou plusieurs Clés et localiser cette ligne, on peut utiliser la méthode Seek fournie par TiKV pour localiser rapidement l'emplacement de cette ligne de données. Un autre exemple est la nécessité d'analyser la table entière. Si elle peut être mappée sur une plage de clés et analysée de StartKey à EndKey, alors les données entières de la table peuvent être obtenues simplement de cette manière. La même idée s’applique aux données d’exploitation de l’index. Voyons ensuite comment TiDB procède.
TiDB attribue un TableID à chaque table, un IndexID à chaque index et un RowID à chaque ligne (si la table a une clé primaire entière, la valeur de la clé primaire sera utilisée comme RowID), où le TableID est unique dans l'ensemble du cluster. , IndexID/RowID sont uniques dans la table et ces ID sont tous de type int64.
Chaque ligne de données est codée dans une paire clé-valeur selon les règles suivantes :
Clé : tablePrefix{tableID}_recordPrefixSep{rowID}
Valeur : [col1, col2, col3, col4]
où tablePrefix/recordPrefixSep de Key sont des constantes de chaîne spécifiques, utilisation Utilisé pour distinguer d'autres données dans l'espace KV.
Pour les données d'index, elles seront codées dans une paire clé-valeur selon les règles suivantes :
Clé : tablePrefix{tableID}_indexPrefixSep{indexID}_indexedColumnsValue
Valeur : rowID
Les données d'index doivent également prendre en compte les deux situations d'index unique et d'index non unique. Pour l'index unique, les règles de codage ci-dessus peuvent être suivies. Mais pour un index non unique, une clé unique ne peut pas être construite via cet encodage, car les tablePrefix{tableID}_indexPrefixSep{indexID} du même index sont les mêmes et la ColumnsValue de plusieurs lignes de données peut être la même, donc pour Index non unique L'encodage a été légèrement ajusté :
Clé : tablePrefix{tableID}_indexPrefixSep{indexID}_indexedColumnsValue_rowID
Valeur : null
De cette façon, une clé unique peut être construite pour chaque ligne de données dans l'index.
Notez que les différents xxPrefixes de la clé dans les règles de codage ci-dessus sont tous des constantes de chaîne et que leur fonction est de distinguer les espaces de noms pour éviter les conflits entre les différents types de données. Ils sont définis comme suit : var(​ tablePrefix = []byte{'
t
' }
​ recordPrefixSep = []byte(“_r”)
​ indexPrefixSep = []byte(“_i”)
)
De plus, veuillez noter que dans le schéma ci-dessus, quel que soit le schéma de codage de clé de Row ou Index, toutes les lignes dans un tableau ont le même préfixe, les données d'un index ont également le même préfixe. De cette manière, les données portant le même préfixe sont regroupées dans l'espace clé de TiKV.
Dans le même temps, tant que nous concevons soigneusement le schéma de codage de la partie suffixe pour garantir que la relation de comparaison entre avant et après le codage reste inchangée, les données de ligne ou d'index peuvent être stockées dans TiKV de manière ordonnée. Ce schéma qui garantit que la relation de comparaison avant et après le codage reste inchangée est appelé Memcomparable. Pour tout type de valeur, le résultat de la comparaison de type d'origine des deux objets avant le codage est comparé au résultat après le codage dans un tableau d'octets (notez que la clé dans TiKV et la valeur sont toutes deux des tableaux d'octets d'origine), les résultats de la comparaison sont cohérents. Après avoir utilisé ce codage, toutes les données de ligne d'une table seront disposées dans l'espace clé de TiKV dans l'ordre de RowID, et les données d'un certain index seront également disposées dans l'espace clé dans l'ordre de ColumnValue de l'index.
Jetons maintenant un œil aux exigences mentionnées au début et à la solution de cartographie de TiDB pour voir si cette solution peut répondre aux besoins.
Tout d’abord, nous utilisons ce schéma de mappage pour convertir les données de ligne et d’index en données clé-valeur, et chaque ligne et chaque donnée d’index ont une clé unique.
Deuxièmement, ce schéma de mappage est convivial pour les requêtes de point et les requêtes de plage. Nous pouvons facilement construire la clé correspondant à une certaine ligne ou à un certain index, ou la clé correspondante d'une certaine ligne adjacente ou d'une certaine valeur d'index adjacente.Plage de clés.
Enfin, lorsque vous garantissez certaines contraintes dans le tableau, vous pouvez déterminer si les contraintes correspondantes peuvent être satisfaites en construisant et en vérifiant si une certaine clé existe.
Jusqu'à présent, nous avons fini de parler de la façon de mapper une table en KV. Voici un exemple simple que tout le monde peut comprendre, prenons la structure de table ci-dessus comme exemple. Supposons qu'il y ait 3 lignes de données dans le tableau :
1, "TiDB", "SQL Layer", 10
2, "TiKV", "KV Engine", 20
3, "PD", "Manager", 30
Ensuite, chaque ligne de données sera mappée sur une paire clé-valeur. Notez que cette table a une clé primaire de type Int, donc la valeur de RowID est la valeur de cette clé primaire. Supposons que l'ID de table de cette table est 10 et que ses données de ligne sont :
t10_r1 --> ["TiDB", "SQL Layer", 10]
t10_r2 --> ["TiKV", "KV Engine", 20]
t10_r3 -> ["PD", "Manager", 30]
En plus de la clé primaire, cette table possède également un index. Supposons que l'ID de cet index soit 1, alors ses données sont :
t10_i1_10_1 --> null
t10_i1_20_2 - -> nul
t10_i1_30_3 - -> nul

gestion des méta-informations

La section précédente a présenté comment les données et les index de la table sont mappés à KV. Cette section présente le stockage des méta-informations. La base de données/table contient toutes des méta-informations, c'est-à-dire leur définition et divers attributs. Ces informations doivent également être conservées, et nous stockons également ces informations dans TiKV. Chaque base de données/table se voit attribuer un identifiant unique, qui sert d'identifiant unique, et lors du codage en tant que valeur-clé, cet identifiant sera codé dans la clé, plus le préfixe m_. De cette manière, une clé peut être construite et les métainformations sérialisées sont stockées dans la valeur.

De plus, il existe une valeur-clé spéciale qui stocke la version des informations de schéma actuelles. TiDB utilise l'algorithme de changement de schéma en ligne de Google F1. Il existe un fil d'arrière-plan qui vérifie en permanence si la version du schéma stockée sur TiKV a changé et garantit que le changement de version peut être obtenu dans un certain laps de temps (s'il change)

SQL sur l'architecture KV

La fonction principale de TiKV Cluster est de stocker des données en tant que moteur KV. Les détails ont été introduits auparavant et ne seront pas décrits ici. Ici, nous introduisons principalement la couche SQL, qui est la couche des serveurs TiDB. Les nœuds de cette couche sont des nœuds sans état et ne stockent pas de données eux-mêmes. Les nœuds sont complètement égaux. Le travail le plus important de cette couche de TiDB Server est de traiter les demandes des utilisateurs et d'exécuter la logique d'opération SQL. Ensuite, nous ferons quelques brèves introductions.

Opérations SQL

​ Après avoir compris le schéma de mappage de SQL vers KV, nous pouvons comprendre comment les données relationnelles sont stockées. Ensuite, nous devons comprendre comment utiliser ces données pour répondre aux besoins de requête de l'utilisateur, c'est-à-dire comment une instruction de requête fonctionne sur le sous-jacent stocké. données.
La solution la plus simple à laquelle on puisse penser consiste à utiliser la solution de mappage décrite dans la section précédente pour mapper la requête SQL en requête KV, puis à obtenir les données correspondantes via l'interface KV et enfin à effectuer divers calculs.
Par exemple, Select count(*) from user Where name="TiDB" ; Pour une telle instruction, nous devons lire toutes les données de la table, puis vérifier si le champ Nom est TiDB. Si tel est le cas, renvoyez cette ligne. Un tel processus d'exploitation est converti en un processus d'exploitation KV :

  • Construisez la plage de clés : tous les RowID d'une table sont dans la plage [0, MaxInt64), puis nous utilisons 0 et MaxInt64 selon les règles de codage de clé de la ligne pour construire un [StartKey, EndKey) fermé à gauche et ouvert à droite. intervalle
  • Scan Key Range : lisez les données dans TiKV en fonction de la plage de clés construite ci-dessus
  • Filtrer les données : Pour chaque ligne de données lue, calculez l'expression name="TiDB". Si elle est vraie, renvoyez cette ligne vers le haut, sinon supprimez cette ligne de données.
  • Calculer le nombre : pour chaque ligne qui répond aux exigences, accumulez la valeur du nombre. La solution ci-dessus peut certainement fonctionner, mais elle ne fonctionne pas très bien. La raison est évidente :
    • Lors de l'analyse des données, chaque ligne doit être lue à partir de TiKV via l'opération KV, ce qui nécessite au moins une surcharge RPC. S'il y a beaucoup de données à analyser, cette surcharge sera très importante.
    • Toutes les lignes ne sont pas utiles. Si les conditions ne sont pas remplies, vous n’avez pas besoin de les lire.
    • Les valeurs des lignes qui répondent aux exigences n'ont aucun sens. En fait, les informations sur le nombre de lignes de données nécessaires ici sont suffisantes.

Opérations SQL distribuées

Il est également évident comment éviter les défauts ci-dessus,

Tout d'abord, nous devons déplacer le calcul le plus près possible du nœud de stockage pour éviter un grand nombre d'appels RPC.

Deuxièmement, nous devons pousser le filtre vers le nœud de stockage pour le calcul, de sorte que seules les lignes valides doivent être renvoyées pour éviter une transmission réseau inutile.

Enfin, nous pouvons pousser la fonction d'agrégation et GroupBy vers le nœud de stockage pour la pré-agrégation. Chaque nœud n'a besoin que de renvoyer une valeur Count, puis tidb-server fera la somme de la valeur Count.

Voici un diagramme schématique des données renvoyées couche par couche :

Architecture de la couche SQL

Les sections ci-dessus présentent brièvement certaines fonctions de la couche SQL. J'espère que tout le monde a une compréhension de base du traitement des instructions SQL. En fait, la couche SQL de TiDB est beaucoup plus compliquée, avec de nombreux modules et niveaux. La figure suivante répertorie les modules importants et les relations d'appel :

​ La requête SQL de l'utilisateur sera envoyée au serveur tidb directement ou via Load Balancer. Le serveur tidb analysera le paquet de protocole MySQL, obtiendra le contenu de la requête, puis effectuera une analyse syntaxique, la formulation et l'optimisation du plan de requête, et exécutera le plan de requête. pour obtenir et traiter des données.

Toutes les données sont stockées dans le cluster TiKV, donc dans ce processus, le serveur tidb doit interagir avec le serveur tikv pour obtenir des données.

Enfin, le serveur tidb doit renvoyer les résultats de la requête à l'utilisateur

Planification des tâches

Pourquoi planifier

Rappelons d'abord l'histoire intérieure de la technologie TiDB - le stockage de certaines des informations mentionnées. Le cluster TiKV est le moteur de stockage KV distribué de la base de données TiDB. Les données sont répliquées et gérées en unités de région. Chaque région aura plusieurs répliques (répliques ). Ces répliques seront distribuées sur différents nœuds TiKV, où le leader est responsable de la lecture/écriture, et le suiveur est responsable de la synchronisation du journal du radeau envoyé par le leader. Maintenant que vous disposez de ces informations, réfléchissez à ces questions :

  • Comment garantir que plusieurs réplicas de la même région sont distribués sur différents nœuds ? De plus, quels sont les problèmes si plusieurs instances TiKV sont démarrées sur une seule machine ?
  • Lorsque le cluster TiKV est déployé dans des salles informatiques pour une reprise après sinistre, comment garantir que si une salle informatique est hors ligne, plusieurs répliques du groupe Raft ne seront pas perdues ?
  • Après avoir ajouté un nœud au cluster TiKV, comment déplacer les données des autres nœuds du cluster ?
  • Quels problèmes se produisent lorsqu’un nœud se déconnecte ? Que doit faire l’ensemble du cluster ? Que faire si le nœud n'est que temporairement hors ligne (redémarrage du service) ? Que faire si un nœud est hors ligne pendant une longue période (panne de disque, toutes les données sont perdues) ?
  • Supposons que le cluster nécessite N réplicas pour chaque groupe Raft. Pour un seul groupe Raft, le nombre de réplicas peut ne pas être suffisant (par exemple, un nœud se déconnecte et perd des réplicas), ou il peut être trop élevé (par exemple, un le nœud qui se déconnecte revient à la normale). , rejoint automatiquement le cluster). Alors comment ajuster le nombre de Replica ?
  • La lecture/écriture s'effectue via le Leader. Si le Leader n'est concentré que sur un petit nombre de nœuds, quel impact aura-t-il sur le cluster ?
  • Toutes les régions ne sont pas fréquemment consultées. Les points d'accès peuvent se trouver uniquement dans quelques régions. Que devons-nous faire à ce stade ?
  • Lorsqu'un cluster effectue un équilibrage de charge, il est souvent nécessaire de migrer des données. Cette migration de données occupera-t-elle beaucoup de bande passante réseau, d'E/S disque et de CPU ? Et puis affecter les services en ligne ?

​ Ces problèmes peuvent avoir des solutions simples lorsqu’ils sont pris individuellement, mais lorsqu’ils sont mélangés, ils ne sont pas faciles à résoudre. Certains problèmes semblent nécessiter uniquement la prise en compte de la situation interne d'un seul groupe Raft, comme par exemple décider d'ajouter ou non des répliques en fonction de la suffisance du nombre de répliques. Mais en réalité, là où cette copie est ajoutée, il faut prendre en compte une information globale. L'ensemble du système évolue également de manière dynamique. Les divisions de régions, les ajouts de nœuds, les échecs de nœuds, les changements dans les points d'accès, etc. continueront à se produire. L'ensemble du système de planification doit également évoluer continuellement vers l'état optimal de manière dynamique. Si personne Dispose d'informations globales, il peut contrôler la situation globale. Avec des composants qui peuvent être planifiés et configurés, il est difficile de répondre à ces besoins. Par conséquent, nous avons besoin d’un nœud central pour contrôler et ajuster l’état global du système, nous avons donc le module PD.

Besoins en matière de planification

De nombreuses questions sont énumérées ci-dessus, classons-les et organisons-les d’abord. De manière générale, il existe deux grandes catégories de problèmes :
1. En tant que système de stockage distribué à haute disponibilité, quatre exigences doivent être remplies :

  • Le nombre de copies ne peut pas être supérieur ou inférieur

  • Les répliques doivent être distribuées sur différentes machines

  • Après avoir ajouté un nouveau nœud, vous pouvez migrer les réplicas sur d'autres nœuds.

  • Une fois qu'un nœud est hors ligne, les données du nœud doivent être migrées.
    2. En tant que bon système distribué, les domaines qui doivent être optimisés incluent :

  • Maintenir une répartition uniforme des leaders dans tout le cluster

  • Maintenir une capacité de stockage uniforme de chaque nœud

  • Maintenir une répartition uniforme des points d'accès

  • Contrôlez la vitesse de Balance pour éviter d’affecter les services en ligne

  • Gérez l’état des nœuds, notamment en mettant manuellement les nœuds en ligne/hors ligne et en mettant automatiquement hors ligne les nœuds défaillants.

Après avoir satisfait au premier type d'exigences, l'ensemble du système aura les fonctions de tolérance aux pannes multi-copies, d'expansion/réduction dynamique, de tolérance de déconnexion des nœuds et de récupération automatique des erreurs.
Après avoir satisfait au deuxième type d’exigences, la charge du système global peut être rendue plus uniforme et peut être facilement gérée.
Afin de répondre à ces besoins, nous devons d'abord collecter suffisamment d'informations, telles que l'état de chaque nœud, les informations de chaque groupe Raft, les statistiques des opérations d'accès aux entreprises, etc. ; et deuxièmement, nous devons définir certaines politiques. sur ces informations
et les politiques de planification. Élaborer un plan de planification qui répond autant que possible aux besoins susmentionnés ; enfin, certaines opérations de base sont nécessaires pour compléter le plan de planification.

Opérations de base de planification

Introduisons d'abord le point le plus simple, qui est l'opération de base de la planification, c'est-à-dire quelles fonctions nous pouvons utiliser pour répondre à la stratégie de planification. C'est la base de toute la programmation. Ce n'est que lorsque vous comprendrez quel type de marteau vous avez dans votre main que vous pourrez savoir quelle posture utiliser pour briser les clous.

Les exigences de planification ci-dessus peuvent sembler compliquées, mais la mise en œuvre finale n'est rien de plus que les trois choses suivantes :

  • Ajouter une réplique

  • Supprimer une réplique

  • Transférer le rôle de Leader entre différentes répliques d'un groupe Raft

Il se trouve que le protocole Raft peut répondre à ces trois besoins : grâce aux trois commandes AddReplica, RemoveReplica et TransferLeader, il peut prendre en charge les trois opérations de base ci-dessus.

recueillir un message

La planification repose sur la collecte d'informations sur l'ensemble du cluster. En termes simples, nous devons connaître l'état de chaque nœud TiKV et l'état de chaque région. Le cluster TiKV rapportera deux types de messages au PD :
 Chaque nœud TiKV rapportera régulièrement les informations globales du nœud au PD.
Il existe un paquet de battements de cœur entre le nœud TiKV (Store) et le PD. D'une part, le PD détecte si chaque magasin est actif via le paquet de battement de cœur et s'il existe un magasin nouvellement ajouté ; d'autre part, le paquet de battement de cœur contiendra également les informations d'état de ce magasin, comprenant principalement :

  • capacité totale du disque
  • Capacité disque disponible
  • Nombre de régions transportées
  • Vitesse d'écriture des données
  • Nombre d'instantanés envoyés/reçus (les données peuvent être synchronisées entre la réplique et l'instantané)
  • Est-ce surchargé ?
  • Informations sur les balises (une balise est une série de balises avec une relation hiérarchique)

Le chef de chaque groupe de radeau rapportera régulièrement des informations au PD.
Il existe un paquet de battements de cœur entre le chef de chaque groupe de radeau et le PD, qui est utilisé pour rapporter l'état de la région, qui comprend principalement les informations suivantes :

  • La position du leader
  • Emplacement des abonnés
  • Nombre de réplicas hors ligne
  • Vitesse d'écriture/lecture des données

PD collecte en permanence des informations sur l'ensemble du cluster via ces deux types de messages de pulsation, puis utilise ces informations comme base de prise de décision. De plus, PD peut également recevoir des informations supplémentaires via l'interface de gestion pour prendre des décisions plus précises. Par exemple, lorsque le paquet de battements de cœur d'un certain magasin est interrompu, PD ne peut pas déterminer si le nœud est en panne temporairement ou définitivement. Il ne peut attendre qu'un certain temps (30 minutes par défaut). S'il n'y a pas de paquet de battements de cœur, il est considéré comme un échec du Store. Mettez-vous hors ligne, puis décidez que toutes les régions de ce Store doivent être planifiées. Mais parfois, le personnel d'exploitation et de maintenance prend l'initiative de mettre une certaine machine hors ligne. À ce moment, le PD peut être informé que le magasin n'est pas disponible via l'interface de gestion PD, et le PD peut immédiatement déterminer que toutes les régions du magasin doivent être programmés à l'écart.

Stratégie de planification

Une fois que PD a collecté ces informations, il lui faut également des stratégies pour élaborer des plans de planification spécifiques.

  1. Le nombre de répliques dans une région est correct.
    Lorsque PD découvre que le nombre de répliques dans cette région ne répond pas aux exigences via le paquet de battements de cœur d'un chef de région, il doit ajuster le nombre de répliques via l'opération Ajouter/Supprimer une réplique. . Les raisons possibles pour cela sont les suivantes :
    • Lorsqu'un nœud est hors ligne, toutes les données qu'il contient sont perdues, ce qui entraîne des réplicas insuffisants dans certaines régions.

    • Un certain nœud hors ligne reprend le service et se connecte automatiquement au cluster. De cette façon, le nombre de répliques dans la région qui a déjà rempli la réplique dépasse le nombre et une certaine réplique doit être supprimée.

  • L'administrateur a ajusté la stratégie de réplication et modifié la configuration de max-replicas

2. Plusieurs répliques d'un groupe Raft ne se trouvent pas au même emplacement.
Veuillez noter le deuxième point : "Plusieurs répliques d'un groupe Raft ne se trouvent pas au même emplacement". Le terme "même emplacement" est utilisé ici au lieu de "même nœud". ". . Dans des circonstances normales, PD garantira uniquement que plusieurs réplicas ne tombent pas sur un seul nœud pour éviter la perte de plusieurs réplicas en raison de la défaillance d'un seul nœud. Lors d'un déploiement réel, les exigences suivantes peuvent également survenir :

  • Plusieurs nœuds déployés sur la même machine physique

  • Les nœuds TiKV sont répartis sur plusieurs racks et on espère que la disponibilité du système pourra être garantie même lorsqu'un seul rack est hors tension.

  • Les nœuds TiKV sont distribués dans plusieurs IDC. On espère que lorsqu'une seule salle informatique est hors tension, le système pourra être assuré. Ces
    exigences sont essentiellement qu'un certain nœud ait des attributs d'emplacement communs, formant une unité minimale tolérante aux pannes. Nous espérons qu'il n'y aura aucun défaut à l'intérieur de cette unité. Il existe plusieurs répliques d'une région. À ce stade, vous pouvez configurer des étiquettes pour le nœud et spécifier quelles étiquettes sont des identifiants d'emplacement en configurant des étiquettes d'emplacement sur le PD. Lors de l'allocation de la réplique, essayez de vous assurer qu'il n'y aura pas plusieurs nœuds de réplique d'une région avec le même identifiant d'emplacement. . .

3. Les répliques sont réparties uniformément entre les magasins
. Comme mentionné précédemment, la limite supérieure de la capacité de données stockées dans chaque réplique est fixe, nous maintenons donc un nombre équilibré de répliques sur chaque nœud, ce qui rendra la charge globale plus équilibrée.
4. Le nombre de leaders est réparti uniformément entre les magasins.
Le protocole Raft lit et écrit via le leader, de sorte que la charge de calcul repose principalement sur le leader, et PD répartira le leader entre les nœuds autant que possible.
5. Le nombre de points d'accès d'accès est réparti uniformément entre les magasins.
Chaque magasin et chef de région transporte des informations sur la charge d'accès actuelle lorsqu'il rapporte des informations, telles que la vitesse de lecture/écriture de la clé. PD détecte les points d'accès d'accès et les répartit entre les nœuds.
6. L'espace de stockage occupé par chaque Store est à peu près égal.
Lorsque chaque Store est démarré, un paramètre Capacité est spécifié, indiquant la limite supérieure de l'espace de stockage de ce Store. PD prendra en compte l'espace de stockage restant du nœud lors de la planification.
7. Contrôlez la vitesse de planification pour éviter d'affecter les services en ligne.
Les opérations de planification consomment du processeur, de la mémoire, des E/S disque et de la bande passante réseau. Nous devons éviter d'avoir trop d'impact sur les services en ligne. PD contrôlera le nombre d'opérations en cours. Le contrôle de vitesse par défaut est relativement conservateur. Si vous souhaitez accélérer la planification (par exemple, si vous avez arrêté les mises à niveau de service, ajouté de nouveaux nœuds et souhaitez planifier le plus tôt possible), vous pouvez accélérer manuellement la planification grâce à pd-ctl.speed.
8. Prend en charge le nœud manuel hors ligne.
Lorsqu'un nœud est manuellement hors ligne via pd-ctl, PD planifiera les données sur le nœud sous un certain contrôle de débit. Une fois la planification terminée, le nœud sera mis hors ligne.

Mise en place de la planification

Après avoir compris les informations ci-dessus, examinons l'ensemble du processus de planification.

​ PD collecte en continu des informations via les paquets de battement de cœur du magasin ou du leader pour obtenir des données détaillées de l'ensemble du cluster, et génère une séquence d'opérations de planification basée sur ces informations et la politique de planification. Chaque fois qu'il reçoit un paquet de battements de cœur du leader de la région, le PD vérifiera si s'il y a des opérations à effectuer sur cette région, les opérations requises sont renvoyées au chef de région via le message de réponse du paquet de battement de cœur, et les résultats de l'exécution sont surveillés dans les paquets de battement de cœur suivants. Notez que les opérations ici ne sont que des suggestions pour le chef de région et qu'il n'y a aucune garantie qu'elles seront exécutées. Si et quand elles seront exécutées est déterminé par le chef de région lui-même en fonction de son statut actuel.

Je suppose que tu aimes

Origine blog.csdn.net/wt334502157/article/details/126468893
conseillé
Classement