Examen de CockroachDB: une base de données SQL évolutive conçue pour la survie

Jusqu'à très récemment, lorsque vous achetiez une base de données, vous deviez choisir: évolutivité ou cohérence? Les bases de données SQL telles que MySQL garantissent une forte cohérence, mais ne s'adaptent pas bien horizontalement. (Le partitionnement manuel pour l'évolutivité n'est pas une idée amusante pour personne.) Les bases de données NoSQL telles que MongoDB évoluent à merveille, mais n'offrent qu'une cohérence éventuelle. («Attendez assez longtemps et vous pourrez lire la bonne réponse», ce qui n'est pas un moyen d'effectuer des transactions financières.)

Google Cloud Spanner, un service de base de données relationnelle entièrement géré fonctionnant sur Google Compute Engine (GCE) sorti en février 2017, offre l'évolutivité des bases de données NoSQL tout en conservant la compatibilité SQL, les schémas relationnels, les transactions ACID et une forte cohérence externe. Spanner est une base de données relationnelle fragmentée, distribuée et répliquée dans le monde entier qui utilise un algorithme Paxos pour atteindre un consensus entre ses nœuds.

Une alternative à Spanner, et le sujet de cette revue, est CockroachDB, une base de données SQL distribuée et évolutive horizontalement open source développée par d'anciens googleurs qui connaissaient Spanner. CockroachDB emprunte à Spanner de Google pour la conception de son système de stockage de données, et utilise un algorithme Raft pour parvenir à un consensus entre ses nœuds.

Comme Cloud Spanner, CockroachDB est une base de données SQL distribuée construite au-dessus d'un magasin de valeurs-clés transactionnel et cohérent, dans le cas de CockroachDB sur RocksDB. Les principaux objectifs de conception de CockroachDB sont la prise en charge des transactions ACID, l'évolutivité horizontale et (surtout) la survie, d'où son nom.

CockroachDB est conçu pour survivre aux pannes de disque, de machine, de rack et même de centre de données avec une interruption de latence minimale et aucune intervention manuelle. Bien sûr, pour ce faire, vous devez exécuter un cluster de nombreuses instances des nœuds symétriques de CockroachDB, en utilisant plusieurs disques, machines, racks et centres de données.

Contrairement à Cloud Spanner, qui utilise l'API TrueTime disponible pour la synchronisation de l'heure dans les centres de données Google, CockroachDB ne peut pas compter sur la présence d'horloges atomiques et d'horloges satellites GPS pour synchroniser l'heure avec précision entre les nœuds et les centres de données. Cela a plusieurs implications. Pour commencer, Google TrueTime donne une limite supérieure pour les décalages d'horloge entre les nœuds dans un cluster de sept millisecondes. C'est suffisamment petit pour qu'un nœud Spanner n'attende que sept millisecondes après une écriture avant de signaler qu'une transaction a été validée, pour garantir la cohérence externe.

Sans TrueTime ou une installation similaire, CockroachDB doit revenir à NTP, qui donne des limites supérieures sur la synchronisation d'horloge entre 100 millisecondes et 250 millisecondes. Compte tenu de cette fenêtre de temps plus longue, CockroachDB n'attend pas après les écritures. Au lieu de cela, il attend parfois avant les lectures, redémarrant essentiellement une transaction s'il lit une valeur avec un horodatage supérieur au début de la transaction, encore une fois pour garantir la cohérence.

Lorsque tous les nœuds d'un cluster CockroachDB ont les petites limites supérieures pour les décalages d'horloge que vous pouvez obtenir à partir des horloges GPS ou atomiques, ce qui est en train de devenir disponible sur les principaux nuages ​​publics, il peut être logique de les exécuter avec le --linearizable drapeau. Cela les fait attendre le décalage d'horloge maximum avant de renvoyer une validation réussie, tout comme Spanner.

Comment fonctionne CockroachDB

Chaque nœud CockroachDB se compose de cinq couches:

  • SQL, qui convertit les requêtes SQL client en opérations clé-valeur
  • Transaction, qui permet des modifications atomiques de plusieurs entrées clé-valeur
  • Distribution, qui présente les plages de valeurs-clés répliquées sous la forme d'une seule entité
  • La réplication, qui réplique de manière cohérente et synchrone les plages de valeurs-clés sur de nombreux nœuds, et permet des lectures cohérentes via des baux
  • Stockage, qui écrit et lit des données clé-valeur sur disque

La couche SQL analyse les requêtes sur un fichier Yacc et les transforme en une arborescence de syntaxe abstraite. À partir de l'arborescence de syntaxe abstraite, CockroachDB génère une arborescence de nœuds de plan, qui contiennent du code clé-valeur. Les nœuds de plan sont ensuite exécutés, communiquant avec la couche de transaction.

La couche de transaction implémente la sémantique de transaction ACID avec des validations en deux phases sur l'ensemble du cluster, y compris les transactions inter-plages et inter-tables, en traitant les instructions uniques comme des transactions (également appelé mode de validation automatique). La validation en deux phases est accomplie en publiant des enregistrements de transaction et des intentions d'écriture, en exécutant des opérations de lecture et en traitant toutes les intentions d'écriture rencontrées comme des conflits de transaction.

La couche de distribution reçoit des demandes de la couche de transaction sur le même nœud. Il identifie ensuite les nœuds qui doivent recevoir la demande et envoie la demande à la couche de réplication du nœud approprié.

La couche de réplication copie les données entre les nœuds et assure la cohérence entre ces copies en implémentant un algorithme de consensus Raft. Vous pouvez contrôler le facteur de réplication au niveau du cluster, de la base de données et de la table à l'aide des zones de réplication. L'algorithme de consensus est utilisé uniquement pour les écritures et nécessite qu'un quorum de répliques accepte les modifications apportées à une plage avant que ces modifications ne soient validées.

La couche de stockage stocke les données sous forme de paires clé-valeur sur le disque à l'aide de RocksDB. CockroachDB s'appuie fortement sur le contrôle d'accès concurrentiel multi-version (MVCC) pour traiter les demandes simultanées et garantir la cohérence. Une grande partie de ce travail est effectuée en utilisant des horodatages d'horloge logique hybride (HLC).

Comme Spanner, CockroachDB prend en charge les requêtes de voyage dans le temps (activées par MVCC). Ceux-ci peuvent remonter aussi loin que votre garbage collection de base de données le plus récent, effectué par défaut quotidiennement.

Installation et utilisation de CockroachDB

CockroachDB fonctionne sur les systèmes d'exploitation Mac, Linux et Windows, au moins pour le développement et les tests. Les bases de données Production Cockroach s'exécutent généralement sur des machines virtuelles Linux ou des conteneurs orchestrés, souvent hébergés sur des clouds publics dans plusieurs centres de données. Le binaire Windows de CockroachDB est toujours en phase bêta et n'est pas recommandé pour la production, et Apple ne fabrique plus de matériel serveur.

Laboratoires de cafards

Comme vous pouvez le voir dans la capture d'écran ci-dessus, il existe quatre options pour installer CockroachDB sur un Mac. J'ai choisi Homebrew comme probablement le plus simple des quatre.

À propos, Cockroach Labs publie un avertissement sur le site indiquant que l'exécution d'une application avec état telle que CockroachDB dans Docker est délicate, déconseillée pour les déploiements en production, et d'utiliser un outil d'orchestration comme Kubernetes ou Docker Swarm pour exécuter un cluster à la place. Je discuterai des options d'orchestration de conteneurs dans la section suivante.

L'installation sur un Mac est aussi simple que brew install cockroachcelle illustrée ci-dessus. Dans mon cas, la mise à jour automatique de Homebrew a pris beaucoup plus de temps (assez de temps pour préparer du thé) que l'installation réelle de CockroachDB, qui n'a pris que quelques secondes.

Une fois que CockroachDB est installé, il est assez facile de lancer un cluster local, bien qu'il existe une étape supplémentaire de génération de certificats de sécurité avec la cockroach certcommande si vous voulez que le cluster soit sécurisé. Une fois que vous avez un cluster en cours d'exécution (en utilisant la cockroach startcommande une fois pour chaque nœud, avec les nœuds suivants définis pour rejoindre le cluster du premier nœud), vous pouvez vous connecter à la page d'administration Web sur n'importe quel nœud avec un navigateur et utiliser le cockroach sqlclient intégré pour envoyer SQL requêtes vers n'importe quel nœud. La plupart des navigateurs se plaindront des sites avec des certificats générés par CockroachDB, mais vous devriez pouvoir cliquer sur ce terrible avertissement et continuer sur le site.

Les paramètres de production recommandés pour CockroachDB sont différents des paramètres par défaut, qui ont été définis pour les instances de développement et de test. Vous pouvez développer sur un cluster à un nœud si vous le souhaitez. Pour la production, vous devez disposer d'au moins trois nœuds, exécuter chaque nœud sur une machine, une machine virtuelle ou un conteneur distinct et donner à chaque instance un cache et une mémoire SQL supplémentaires. Les paramètres par défaut sont de 128 Mo chacun pour le cache et la mémoire SQL; les paramètres de production recommandés sont de donner à chacun 25% de RAM:

cockroach start --cache=25% --max-sql-memory=25%

Plus vous exécutez de nœuds, meilleure sera la résilience. Plus les nœuds sont gros et rapides, meilleures sont les performances. Si vous voulez avoir des nœuds avec des performances à peu près comparables à celles des nœuds Google Cloud Spanner, qui fournissent 2000 écritures par seconde et 10000 lectures par seconde, alors vous voudriez quelque chose comme les instances n1-highcpu-8 de GCE, qui ont huit processeurs et 8 Go de RAM. , avec des disques SSD locaux (plutôt que des disques rotatifs).

Plus vous distribuez vos nœuds à différents centres de données, mieux vous pouvez garantir l'immunité aux pannes au niveau du centre de données. Il y a cependant un coût: la latence aller-retour entre les centres de données aura un effet direct sur les performances de votre base de données, les clusters intercontinentaux fonctionnant nettement moins bien que les clusters dans lesquels tous les nœuds sont géographiquement proches les uns des autres.

Cockroach Labs fournit des instructions détaillées pour le déploiement sur AWS, Digital Ocean, GCE et Azure. Les configurations recommandées utilisent des équilibreurs de charge, soit les services d'équilibrage de charge gérés natifs ou des équilibreurs de charge open source tels que HAProxy.

L'orchestration peut réduire la charge de fonctionnement d'un cluster CockroachDB à presque rien. Cockroach Labs explique comment procéder pour la production avec Kubernetes et Docker Swarm. Le référentiel CockroachDB-CloudFormation sur GitHub montre comment utiliser AWS CloudFormation et Kubernetes dans une seule zone de disponibilité pour le développement et les tests. L'adapter à la production impliquerait de modifier le modèle CloudFormation pour utiliser plusieurs zones de disponibilité.

Programmation et tests de CockroachDB

CockroachDB prend en charge le protocole filaire PostgreSQL, vous écrivez donc votre code comme si vous programmiez contre Postgres, ou au moins un sous-ensemble de Postgres. Cette page répertorie les pilotes testés pour diverses liaisons de langage de programmation, y compris les langages côté serveur les plus courants. Cette page répertorie des exemples dans 10 langages de programmation et cinq ORM. Je n'ai pas rencontré de grandes surprises en lisant le code, bien que j'aie repéré quelques bogues mineurs probables dans les listes de la documentation. Vous pouvez également exécuter votre SQL à l'aide du client interactif intégré à l' cockroachexécutable.

Bien qu'il existe un référentiel dédié aux générateurs de charge CockroachDB et un autre pour les tests de performances, l'analyse comparative des clusters CockroachDB n'est pas facile, surtout si vous essayez de comparer CockroachDB à d'autres bases de données de manière significative. Un problème est que le réseau parmi les nœuds peut être l'étape de limitation de débit dans les clusters CockroachDB.

Un autre fait à prendre en compte est que la plupart des bases de données SQL conventionnelles ne s'exécutent pas en mode d'isolation SERIALIZABLE par défaut; à la place, ils utilisent un mode moins strict avec de meilleures performances. CockroachDB utilise le mode d'isolation sérialisable par défaut. De plus, il serait un peu injuste de tester les performances de jointure SQL de CockroachDB, qui sont toujours en cours de travail, avec la suite TPC-C.

Et pourtant, vous pouvez facilement voir la puissance opérationnelle de CockroachDB. Par exemple, de nombreuses bases de données doivent être arrêtées et redémarrées pour les mettre à l'échelle. L'ajout de nœuds sous charge dans CockroachDB est un jeu d'enfant, surtout si vous utilisez un outil d'orchestration. Par exemple, la capture d'écran ci-dessus montre les commandes pour modifier et afficher les nœuds dans un cluster Kubernetes, et la capture d'écran ci-dessous montre le cluster surveillé lorsque les nœuds sont ajoutés. Un outil de génération de charge a fonctionné en continu tout au long du processus.

Une démonstration encore plus impressionnante montre la migration automatique inter-cloud au sein d'un cluster CockroachDB. Il faut vraiment la vidéo pour lui rendre justice; la vidéo est hébergée dans l'article de blog lié.

CafardDB SQL 

SQL dans CockroachDB est plus ou moins standard, contrairement à SQL dans Cloud Spanner, qui utilise une syntaxe non standard pour la manipulation des données. Cependant, il manque encore de nombreuses fonctionnalités à CockroachDB SQL.

Par exemple, la V1.1 ne prend pas en charge JSON, ce qui est prévu pour la V1.2. Il manque également l'analyse XML, qui n'est pas sur la feuille de route. Il manque des cascades au niveau des lignes, prévues pour la V1.2, et des curseurs et des déclencheurs, qui ne sont pas sur la feuille de route. Les index géospatiaux sont des ajouts «potentiels» qui pourraient faire partie de la feuille de route à l'avenir.

Plus particulièrement, l'implémentation initiale de CockroachDB des jointures SQL en 2016 était délibérément simpliste et présentait une mise à l'échelle quadratique, la rendant inutile pour l'interrogation de grands ensembles de données. La version V1.0, réalisée par un étudiant coop, implémentait des jointures par hachage, faisant évoluer de nombreuses opérations de jointure de manière linéaire; qui a amené CockroachDB au niveau de SQLite. À un moment donné en 2018, compte tenu d'un récent cycle de financement, CockroachDB devrait avoir des performances de jointure qui évoluent davantage comme les jointures PostgreSQL, ainsi que le traitement de jointure SQL distribué sur le cluster.