En avril, les ingénieurs d'Avito se sont réunis lors de sessions en ligne avec le principal développeur de ClickHouse, Alexey Milovidov, et Kirill Shvakov, un développeur Golang de la société Integros. Ils ont discuté de la maniÚre dont nous utilisons le systÚme de gestion de bases de données et des difficultés que nous rencontrons.
Suite Ă cette rencontre, nous avons rassemblĂ© un article avec les rĂ©ponses des experts Ă nos questions et Ă celles des spectateurs concernant les sauvegardes, le resharding des donnĂ©es, les dictionnaires externes, le pilote Golang et la mise Ă jour des versions de ClickHouse. Cela pourrait ĂȘtre utile pour les dĂ©veloppeurs qui travaillent dĂ©jĂ activement avec le SGBD de Yandex et s'intĂ©ressent Ă son prĂ©sent et Ă son avenir. Par dĂ©faut, les rĂ©ponses proviennent d'Alexey Milovidov, sauf indication contraire.
Attention, il y a beaucoup de texte sous cette section. Nous espérons que le contenu des questions vous aidera à vous orienter.

Contenu
Si vous ne souhaitez pas lire le texte, vous pouvez regarder l'enregistrement des soirées . Les timestamps sont dans le premier commentaire sous la vidéo.
ClickHouse se met à jour constamment, mais nos données ne le sont pas. Que faire ?
ClickHouse se met à jour constamment, et nos données, qui ont été optimisées avec final, ne sont pas mises à jour et se trouvent dans une sauvegarde.
Supposons qu'un problÚme survienne et que les données soient perdues. Nous avons décidé de nous restaurer, mais il s'est avéré que les anciennes partitions, qui sont stockées sur les serveurs de sauvegarde, divergent fortement de la version actuelle de ClickHouse. Que faire dans cette situation, et est-ce possible ?
Une situation oĂč vous restaurez des donnĂ©es Ă partir d'une sauvegarde dans un ancien format, tandis que la nouvelle version ne les connecte pas, est impossible. Nous veillons Ă ce que le format des donnĂ©es dans ClickHouse soit toujours rĂ©tro-compatible. C'est beaucoup plus important que la rĂ©tro-compatibilitĂ© fonctionnelle, si le comportement d'une fonction rarement utilisĂ©e a changĂ©. Les donnĂ©es stockĂ©es sur le disque doivent toujours pouvoir ĂȘtre lues par la nouvelle version de ClickHouse. C'est une rĂšgle.
Quelles sont les meilleures pratiques actuelles pour la sauvegarde des données de ClickHouse ?
Comment effectuer des sauvegardes en tenant compte que nous avons des opérations d'optimisation finale, une énorme base de données en téraoctets, et des données qui sont mises à jour, supposons, au cours des trois derniers jours, et qu'ensuite aucune procédure n'est effectuée ?
Nous pouvons dĂ©velopper notre propre solution et Ă©crire dans un shell : rassemblez ces sauvegardes de cette maniĂšre. Peut-ĂȘtre qu'il n'est pas nĂ©cessaire de bricoler quoi que ce soit, et que le vĂ©lo a dĂ©jĂ Ă©tĂ© inventĂ© ?
Pour commencer en ce qui concerne les meilleures pratiques. Mes collĂšgues conseillent toujours, en rĂ©ponse aux questions sur les sauvegardes, de rappeler le service « Yandex.Cloud », oĂč cette tĂąche a dĂ©jĂ Ă©tĂ© rĂ©solue. Alors, utilisez-le si vous en avez la possibilitĂ©.
Il n'existe pas de solution complÚte, entiÚrement intégrée à ClickHouse, pour les sauvegardes. Il y a certaines préparations que l'on peut utiliser. Pour obtenir une solution complÚte, il faudra soit passer un peu de temps manuellement, soit créer des wrappers sous forme de scripts.
Je commencerai par les solutions les plus simples et terminerai par les plus sophistiquées, selon le volume de données et la taille du cluster. Plus le cluster est grand, plus la solution devient complexe.
Si la table de données ne fait que quelques gigaoctets, la sauvegarde peut se faire ainsi :
- Enregistrer la dĂ©finition des tables, c'est-Ă -dire les mĂ©tadonnĂ©es â show create table.
- Faire un dump Ă l'aide du client ClickHouse â select * from table dans un fichier. Par dĂ©faut, vous obtiendrez un fichier au format TabSeparated. Si vous souhaitez quelque chose de plus efficace, vous pouvez utiliser le format Native.
Si le volume de données est plus important, la sauvegarde nécessitera plus de temps et d'espace. Cela s'appelle une sauvegarde logique, elle n'est pas liée au format de données de ClickHouse. Si elle existe, vous pourrez dans ce cas charger la sauvegarde dans MySQL pour restauration.
Pour des cas plus avancĂ©s, ClickHouse intĂšgre la possibilitĂ© de crĂ©er des snapshots de partitions dans le systĂšme de fichiers local. Cette fonctionnalitĂ© est accessible sous forme de requĂȘte alter table freeze partition. Ou simplement alter table freeze â ceci est un snapshot de toute la table.
Le snapshot sera créé de maniĂšre cohĂ©rente pour une seule table sur un shard, c'est-Ă -dire qu'il est impossible de crĂ©er un snapshot cohĂ©rent de l'ensemble du cluster de cette maniĂšre. Cependant, pour la plupart des tĂąches, cela n'est pas nĂ©cessaire, et il suffit d'exĂ©cuter la requĂȘte sur chaque shard pour obtenir un snapshot cohĂ©rent. Celui-ci est créé sous forme de hardlinks et ne prend donc pas d'espace supplĂ©mentaire. Ensuite, ce snapshot est copiĂ© sur un serveur de sauvegarde ou dans le stockage utilisĂ© pour les sauvegardes.
Restaurer cette sauvegarde est assez simple. D'abord, vous crĂ©ez les tables selon les dĂ©finitions de table existantes. Ensuite, vous copiez les snapshots de partition sauvegardĂ©s dans Directory-Detached pour ces tables et exĂ©cutez la requĂȘte attach partition. Cette solution convient parfaitement pour les volumes de donnĂ©es les plus sĂ©rieux.
Parfois, il faut quelque chose d'encore plus puissant â dans les cas oĂč vous avez des dizaines, voire des centaines de tĂ©raoctets sur chaque serveur et des centaines de serveurs. Il existe une solution que j'ai vue chez mes collĂšgues de « Yandex.Metrics ». Je ne le conseillerais pas Ă tout le monde â lisez et dĂ©cidez vous-mĂȘme si cela vous convient ou non.
Tout d'abord, vous devez crĂ©er plusieurs serveurs avec de grands racks de stockage. Ensuite, sur ces serveurs, dĂ©ployez plusieurs serveurs ClickHouse et configurez-les pour qu'ils fonctionnent comme une autre rĂ©plique pour les mĂȘmes shards. Ensuite, utilisez un systĂšme de fichiers sur ces serveurs ou un outil qui permet de crĂ©er des instantanĂ©s. Il y a deux options. La premiĂšre option est les instantanĂ©s LVM, la deuxiĂšme option est ZFS sur Linux.
AprĂšs cela, vous devez crĂ©er un instantanĂ© chaque jour, il occupera de l'espace. Naturellement, si les donnĂ©es changent, au fil du temps, l'espace occupĂ© augmentera. Cet instantanĂ© peut ĂȘtre rĂ©cupĂ©rĂ© Ă tout moment pour restaurer les donnĂ©es, c'est une solution Ă©trange. De plus, il faut limiter ces rĂ©pliques dans la configuration pour qu'elles n'essaient pas de devenir des leaders.
Peut-on organiser un retard contrÎlé des réplicas dans les flux ?
Cette année, vous prévoyez de créer des partitions dans ClickHouse. Sera-t-il possible d'organiser un retard contrÎlé des répliques dans celles-ci ? Nous aimerions utiliser cela pour nous protéger contre des scénarios négatifs liés aux altérations et autres modifications.
Est-il possible de faire des rollbacks pour les altérations ? Par exemple, dans une partition existante, il serait possible de dire que jusqu'à ce moment-là , appliquez les modifications, et à partir de ce moment-là , ne les appliquez plus ?
Si une Ă©quipe arrive dans notre cluster et le casse, nous avons une rĂ©plique conditionnelle avec un retard d'une heure, oĂč nous pouvons dire que nous allons l'utiliser pour le moment, mais nous ne prendrons pas en compte les dix derniĂšres minutes de changements ?
Pour commencer, parlons du retard contrĂŽlĂ© des rĂ©pliques. Une telle demande a Ă©tĂ© faite par des utilisateurs, et nous avons créé un problĂšme sur GitHub avec la demande : « Si cela intĂ©resse quelqu'un, laissez un like, mettez un cĆur ». Personne n'a rĂ©agi, et le problĂšme a Ă©tĂ© fermĂ©. NĂ©anmoins, il est dĂ©jĂ possible d'obtenir cette fonctionnalitĂ© en configurant ClickHouse. Cependant, cela ne sera possible qu'Ă partir de la version 20.3.
ClickHouse effectue en permanence des fusions de données en arriÚre-plan - le merge. Lorsque le merge est effectué, un certain ensemble de fragments de données est remplacé par un fragment plus grand. Pendant ce temps, les fragments de données précédents continuent d'exister sur le disque pendant un certain temps.
Tout d'abord, ils continuent d'ĂȘtre stockĂ©s tant qu'il y a des requĂȘtes SELECT qui les utilisent, afin d'assurer un traitement non-bloquant. Les requĂȘtes SELECT peuvent tranquillement lire Ă partir des anciens fragments.
DeuxiĂšmement, il y a aussi un seuil de temps - les anciens fragments de donnĂ©es restent sur le disque pendant huit minutes. Ce dĂ©lai peut ĂȘtre ajustĂ© et transformĂ© en un jour entier. Cela coĂ»tera de l'espace sur le disque : selon le flux de donnĂ©es, les donnĂ©es de la derniĂšre journĂ©e pourraient non seulement doubler, elles pourraient devenir cinq fois plus nombreuses. Mais vous pourrez, en cas de problĂšme sĂ©rieux, arrĂȘter le serveur ClickHouse et tout rĂ©gler.
Maintenant, la question se pose de savoir comment cela protÚge contre les ALTERs. Il convient d'examiner de plus prÚs, car dans les anciennes versions de ClickHouse, l'ALTER fonctionnait de telle maniÚre qu'il modifiait directement les fragments. Il y a un fragment de données avec certains fichiers, et nous réalisons, par exemple, alter drop column. Dans ce cas, cette colonne est physiquement supprimée de tous les fragments.
Mais Ă partir de la version 20.3, le mĂ©canisme des ALTERs a Ă©tĂ© entiĂšrement modifiĂ©, et maintenant les fragments de donnĂ©es sont toujours immutables. Ils ne changent pas du tout - les ALTERs fonctionnent dĂ©sormais Ă peu prĂšs de la mĂȘme maniĂšre que les merges. Au lieu de modifier un fragment sur place, nous en crĂ©ons un nouveau. Dans le nouveau fragment, les fichiers qui n'ont pas changĂ© deviennent des hard links, et si nous avons supprimĂ© une colonne, elle sera simplement absente dans le nouveau fragment. L'ancien fragment sera supprimĂ© par dĂ©faut aprĂšs huit minutes, et il est possible d'ajuster les paramĂštres mentionnĂ©s ci-dessus.
Il en va de mĂȘme pour les ALTERs de type mutations. Lorsque vous effectuez alter delete ou alter update, il ne modifie pas le fragment, mais en crĂ©e un nouveau. Puis, il supprime l'ancien.
Que faire si la structure de la table a changé ?
Comment restaurer une sauvegarde qui a été réalisée avec un ancien schéma ? Et la deuxiÚme question concerne le cas des snapshots et des systÚmes de fichiers. Btrfs convient-il ici à la place de ZFS sur Linux LVM ?
Si vous rĂ©alisez attach partition Si les partitions ont une autre structure, ClickHouse vous dira que ce n'est pas possible. La solution est la suivante. D'abord, crĂ©ez une table temporaire de type MergeTree avec l'ancienne structure, attachez-y les donnĂ©es Ă l'aide de attach, puis effectuez une requĂȘte alter. Ensuite, vous pouvez soit copier ou transfĂ©rer ces donnĂ©es et faire un nouvel attache, soit utiliser la requĂȘte alter table move partition.
Maintenant, la deuxiĂšme question est : peut-on utiliser Btrfs ? Pour commencer, si vous avez LVM, il suffit des snapshots LVM, et le systĂšme de fichiers peut ĂȘtre ext4, cela n'a pas d'importance. Avec Btrfs, tout dĂ©pend de votre expĂ©rience avec. C'est un systĂšme de fichiers mature, mais il subsiste des doutes quant Ă son fonctionnement dans un scĂ©nario spĂ©cifique. Je ne conseillerais pas de l'utiliser si vous n'avez pas Btrfs en production.
Quelles sont les meilleures pratiques actuelles en matiÚre de reshaping des données ?
La question du re-sharding est complexe et multidimensionnelle. Ici, on peut répondre de plusieurs maniÚres. D'un cÎté, on peut dire que ClickHouse n'a pas de capacité intégrée de re-sharding. Mais j'ai peur que cette réponse ne convienne à personne. Donc, on peut également dire que ClickHouse offre plusieurs façons de re-sharder les données.
Si l'espace sur le cluster vient à manquer ou qu'il ne gÚre pas la charge, vous ajoutez de nouveaux serveurs. Mais ces serveurs sont vides par défaut, ils n'ont pas de données et aucune charge ne leur est assignée. Vous devez déplacer des données pour qu'elles soient uniformément réparties sur le nouveau cluster élargi.
La premiĂšre mĂ©thode pour y parvenir est de copier certaines partitions sur de nouveaux serveurs Ă l'aide de la requĂȘte alter table fetch partition. Par exemple, si vous aviez des partitions par mois, vous prenez le premier mois de l'annĂ©e 2017 et vous le copiez sur un nouveau serveur, puis vous copiez le troisiĂšme mois sur un autre nouveau serveur. Et ainsi de suite jusqu'Ă ce que cela devienne assez uniforme.
Le transfert ne peut ĂȘtre effectuĂ© que pour les partitions qui ne changent pas lors de l'Ă©criture. Pour les nouvelles partitions, l'Ă©criture devra ĂȘtre dĂ©sactivĂ©e, car leur transfert n'est pas atomique. Sinon, vous obtiendrez des doublons ou des omissions dans les donnĂ©es. Cela dit, cette mĂ©thode est pratique et fonctionne plutĂŽt efficacement. Les partitions compressĂ©es prĂȘtes sont transfĂ©rĂ©es sur le rĂ©seau, c'est-Ă -dire que les donnĂ©es ne sont pas recompressĂ©es ni re-encodĂ©es.
Cette méthode a un inconvénient, qui dépend de la stratégie de sharding. Vous avez prévu cette méthode de sharding, et quel a été votre clé de sharding. Dans votre exemple pour le cas des métriques, la clé de sharding est le hachage du chemin. Lorsque vous faites un select dans la table distribuée, cela va directement vers tous les shards du cluster et récupÚre les données là -dedans.
Cela signifie que, pour vous, il n'a en fait pas d'importance quelles donnĂ©es se trouvent dans quel shard. L'essentiel est que les donnĂ©es d'un mĂȘme chemin se trouvent dans un seul shard, et peu importe lequel. Dans ce cas, le transfert de partitions prĂȘtes est parfait car lors des requĂȘtes select, avant et aprĂšs le resharding, la structure des valeurs n'a pas vraiment d'importance - vous obtiendrez des donnĂ©es complĂštes.
Mais il arrive aussi des cas plus complexes. Si, au niveau de la logique de l'application, vous vous basez sur une mĂ©thode spĂ©ciale de sharding, par exemple, si ce client est positionnĂ© sur un certain shard, et que la requĂȘte peut ĂȘtre envoyĂ©e directement lĂ -bas, plutĂŽt qu'Ă la table distribuĂ©e. Ou si vous utilisez une version relativement rĂ©cente de ClickHouse et que vous avez activĂ© le paramĂštre optimize skip unused shards. Dans ce cas, lors de la requĂȘte select, l'expression dans la section where sera analysĂ©e et il sera calculĂ© sur quels shards il est nĂ©cessaire d'aller selon la mĂ©thode de sharding. Cela fonctionne Ă condition que les donnĂ©es soient correctement rĂ©parties selon ce schĂ©ma de sharding. Si vous les avez remaniĂ©es manuellement, cette correspondance peut changer.
Donc, c'est la premiÚre méthode. J'attends votre retour pour savoir si cela vous convient ou si nous allons plus loin.
Vladimir Kolobaev, administrateur systĂšme principal chez Avito: Alexey, la mĂ©thode que vous avez mentionnĂ©e ne se prĂȘte pas trĂšs bien Ă la rĂ©partition de la charge, y compris celle de la lecture. Nous pouvons prendre une partition mensuelle et dĂ©placer le mois prĂ©cĂ©dent vers un autre nĆud, mais lorsque la requĂȘte pour ces donnĂ©es arrivera, nous ne chargerons que celui-ci. Ce que nous aimerions, c'est rĂ©partir la charge sur tout le cluster, car sinon, pendant un certain temps, toute la charge de lecture sera traitĂ©e par deux shards.
Alexey Milovidov: La rĂ©ponse est Ă©trange ici - oui, c'est mauvais, mais cela pourrait fonctionner. Je vais expliquer comment. Il faut examiner le scĂ©nario de charge qui accompagne vos donnĂ©es. Si ce sont des donnĂ©es de surveillance, on peut presque dire avec certitude que la grande majoritĂ© des requĂȘtes porte sur des donnĂ©es rĂ©centes.
Vous avez installĂ© de nouveaux serveurs, dĂ©placĂ© d'anciennes partitions, mais vous avez Ă©galement modifiĂ© la façon dont les donnĂ©es rĂ©centes sont enregistrĂ©es. Et ces donnĂ©es rĂ©centes seront dispersĂ©es sur tout le cluster. Ainsi, dĂ©jĂ aprĂšs cinq minutes, les requĂȘtes pour les cinq derniĂšres minutes vont efficacement charger le cluster, et aprĂšs un jour, les requĂȘtes pour les derniĂšres 24 heures vont Ă©galement le faire. En revanche, les requĂȘtes pour le mois prĂ©cĂ©dent, malheureusement, ne seront traitĂ©es que par une partie des serveurs du cluster.
Mais souvent, vous n'aurez pas de requĂȘtes spĂ©cifiquement pour fĂ©vrier 2019. TrĂšs probablement, si les requĂȘtes portent sur l'annĂ©e 2019, elles couvriront l'ensemble de l'annĂ©e, pour une longue pĂ©riode, et non pour une petite plage. Et de telles requĂȘtes pourront Ă©galement charger le cluster de maniĂšre uniforme. Mais dans l'ensemble, votre remarque est tout Ă fait juste, car c'est une solution ad hoc qui ne rĂ©partit pas les donnĂ©es de maniĂšre totalement uniforme.
J'ai encore quelques points à aborder pour répondre à la question. L'un d'eux concerne la maniÚre de concevoir au départ le schéma de sharding pour rendre le résharding moins douloureux. Cela n'est pas toujours possible.
Par exemple, vous avez des donnĂ©es de surveillance. Les donnĂ©es de surveillance augmentent pour trois raisons. La premiĂšre est l'accumulation de donnĂ©es historiques. La deuxiĂšme est l'augmentation du trafic. Et la troisiĂšme est l'accroissement du nombre d'Ă©lĂ©ments qui sont soumis Ă la surveillance. De nouveaux microservices et mĂ©triques apparaissent, qui doivent ĂȘtre conservĂ©s.
Il est possible que la plus forte croissance soit liĂ©e Ă la troisiĂšme raison - l'augmentation de l'utilisation de la surveillance. Dans ce cas, il convient d'examiner la nature de la charge, quelles sont les principales requĂȘtes pour le select. Les principales requĂȘtes pour le select vont probablement concerner un sous-ensemble de mĂ©triques.
Par exemple, l'utilisation du CPU sur certains serveurs par un service quelconque. Il en rĂ©sulte qu'il existe un certain sous-ensemble de clĂ©s Ă partir duquel vous extrayez ces donnĂ©es. Et la requĂȘte pour ces donnĂ©es est trĂšs probablement assez simple et s'exĂ©cute en quelques dizaines de millisecondes. Elle est utilisĂ©e pour les services de surveillance, pour les tableaux de bord. J'espĂšre que je comprends cela correctement.
Vladimir Kolobaev: Le fait est que nous faisons souvent appel à des données historiques, car nous comparons en temps réel la situation actuelle à l'historique. Et il est important pour nous d'avoir un accÚs rapide à un grand volume de données, et ClickHouse gÚre cela trÚs bien.
Vous avez tout Ă fait raison, la plupart des requĂȘtes de lecture que nous rencontrons sont celles de la derniĂšre journĂ©e, comme dans tout systĂšme de surveillance. Cependant, la charge sur les donnĂ©es historiques est Ă©galement assez Ă©levĂ©e. Elle provient principalement du systĂšme d'alerte, qui toutes les trente secondes interroge ClickHouse : « Donne-moi les donnĂ©es des six derniĂšres semaines. Et maintenant, construis-moi une certaine moyenne mobile Ă partir de ces donnĂ©es, et comparons la valeur actuelle Ă l'historique. »
Je voudrais dire qu'il existe pour ces requĂȘtes trĂšs rĂ©centes une petite table supplĂ©mentaire dans laquelle nous stockons seulement deux jours de donnĂ©es, et les requĂȘtes principales vont vers celle-ci. Dans la grande table sharded, nous envoyons uniquement les grosses requĂȘtes historiques.
Alexey Milovidov: Malheureusement, pour votre scénario, cela semble inadapté, mais je vais vous décrire deux schémas de sharding mauvais et complexes qu'il ne faut pas utiliser, mais qui sont utilisés par le service de mes amis.
Il y a un cluster principal avec des Ă©vĂ©nements de « Yandex.Metrica ». Les Ă©vĂ©nements sont des vues de pages, des clics et des transitions. La plupart des requĂȘtes concernent un site web spĂ©cifique. Vous ouvrez le service « Yandex.Metrica », vous avez un site â avito.ru, vous allez dans le rapport et la requĂȘte se fait pour votre site.
Mais il existe aussi d'autres requĂȘtes - analytiques et globales, rĂ©alisĂ©es par des analystes internes. Ă toutes fins utiles, je prĂ©cise que les analystes internes effectuent des requĂȘtes uniquement sur les services de « Yandex ». Cependant, mĂȘme les services de « Yandex » reprĂ©sentent une part substantielle de toutes les donnĂ©es. Ce sont des requĂȘtes non pas sur des compteurs spĂ©cifiques, mais sur une filtration plus large.
Comment organiser les donnĂ©es de maniĂšre Ă ce qu'elles fonctionnent efficacement Ă la fois pour un seul compteur et pour les requĂȘtes globales ? La complexitĂ© rĂ©side Ă©galement dans le fait que le nombre de requĂȘtes dans ClickHouse sur le cluster « MĂ©triques » est de plusieurs milliers par seconde. Avec des requĂȘtes non triviales, par exemple, plusieurs milliers par seconde, un seul serveur ClickHouse ne peut pas le gĂ©rer.
La taille du cluster est d'un peu plus de six cents serveurs. Si l'on se contente d'Ă©tendre une table Distributed sur ce cluster et d'envoyer plusieurs milliers de requĂȘtes, cela ne fera qu'empirer la situation par rapport Ă l'envoi sur un seul serveur. D'un autre cĂŽtĂ©, l'option oĂč les donnĂ©es sont uniformĂ©ment rĂ©parties et oĂč nous interrogeons tous les serveurs est immĂ©diatement Ă©cartĂ©e.
Il existe une option diamĂ©tralement opposĂ©e. Imaginez que nous shardons les donnĂ©es par sites, et qu'une requĂȘte pour un seul site aille sur un seul shard. Le cluster pourrait alors gĂ©rer dix mille requĂȘtes par seconde, mais sur un shard, une seule requĂȘte fonctionnerait beaucoup trop lentement. Elle ne pourra pas Ă©voluer en termes de bande passante, surtout s'il s'agit du site avito.ru. Je ne vais pas rĂ©vĂ©ler de secret en disant qu'Avito est l'un des sites les plus visitĂ©s du Runet. Et traiter cela sur un seul shard serait insensĂ©.
C'est pourquoi le schéma de sharding est conçu de maniÚre plus astucieuse. L'ensemble du cluster est divisé en un certain nombre de petits clusters que nous appelons des couches. à l'intérieur de chaque petit cluster, il y a de dix à plusieurs dizaines de shards. Au total, il y a trente-neuf de ces petits clusters.
Comment cela se dĂ©veloppe-t-il ? Le nombre de petits clusters ne change pas : il y a toujours eu trente-neuf il y a quelques annĂ©es et il en reste ainsi. Mais Ă l'intĂ©rieur de chacun d'eux, nous augmentons progressivement le nombre de shards Ă mesure que les donnĂ©es s'accumulent. Le schĂ©ma de sharding est donc le suivant : la division en ces petits clusters se fait par sites web, et pour comprendre quel site est sur quel petit cluster, nous utilisons une base de donnĂ©es distincte dans MySQL. Un site â un petit cluster. Et Ă l'intĂ©rieur, le sharding se fait par identifiants de visiteurs.
Lors de l'enregistrement, nous les divisons en fonction du reste de la division de l'identifiant du visiteur. Mais lors de l'ajout d'une nouvelle shard, le schĂ©ma de sharding change, nous continuons Ă diviser, mais cette fois selon un autre nombre. Cela signifie qu'un mĂȘme visiteur peut effectivement se trouver sur plusieurs serveurs, et en compter dessus n'est pas une option. Cela a Ă©tĂ© fait uniquement pour amĂ©liorer la compression des donnĂ©es. Lors des requĂȘtes, nous accĂ©dons Ă la table Distributed, qui consulte le cluster et interroge des dizaines de serveurs. VoilĂ un schĂ©ma quelque peu absurde.
Mais mon récit serait incomplet si je ne mentionnais pas que nous avons abandonné ce schéma. Dans le nouveau schéma, tout a été modifié et toutes les données ont été copiées à l'aide de clickhouse-copier.
Dans le nouveau schĂ©ma, tous les sites sont divisĂ©s en deux catĂ©gories : grands et petits. Je ne sais pas comment le seuil a Ă©tĂ© choisi, mais en fin de compte, il s'est avĂ©rĂ© que les grands sites sont enregistrĂ©s sur un cluster avec 120 shards et trois rĂ©pliques chacun - c'est-Ă -dire 360 serveurs. Et le schĂ©ma de sharding est tel que chaque requĂȘte va immĂ©diatement vers tous les shards. Si vous ouvrez maintenant n'importe quelle page de rapport pour avito.ru dans « Yandex.Metrika », la requĂȘte sera envoyĂ©e Ă 120 serveurs. Il y a peu de grands sites dans le RuNet. Et le nombre de requĂȘtes n'atteint pas mille par seconde, mais est mĂȘme infĂ©rieur Ă une centaine. Tout cela est gĂ©rĂ© sans souci par la table Distributed, qui est traitĂ©e par 120 serveurs.
Le deuxiĂšme cluster est destinĂ© aux petits sites. Ici, le schĂ©ma de sharding se fait selon l'identifiant du site, et chaque requĂȘte va prĂ©cisĂ©ment vers un shard.
ClickHouse dispose d'un utilitaire appelé clickhouse-copier. Pouvez-vous en parler ?
Je dois dire tout de suite que cette solution est plus encombrante et un peu moins performante. L'avantage est qu'elle répartit complÚtement les données selon le schéma que vous spécifiez. Mais l'inconvénient de l'utilitaire est qu'il ne réalise pas de re-sharding. Il copie les données d'un schéma de cluster à un autre schéma de cluster.
Cela signifie que pour son fonctionnement, vous devez disposer de deux clusters. Ils peuvent ĂȘtre situĂ©s sur les mĂȘmes serveurs, mais pourtant, les donnĂ©es ne seront pas dĂ©placĂ©es de maniĂšre incrĂ©mentale, mais seront copiĂ©es.
Par exemple, il y avait quatre serveurs, maintenant il y en a huit. Vous crĂ©ez une nouvelle table distribuĂ©e sur tous les serveurs, de nouvelles tables locales et vous lancez clickhouse-copier. Dans celui-ci, vous spĂ©cifiez le schĂ©ma de travail, qu'il doit lire de l'endroit, accepter le nouveau schĂ©ma de sharding et transfĂ©rer les donnĂ©es lĂ -bas. Et vous aurez besoin d'un espace sur les anciens serveurs une fois et demie plus que ce que vous avez actuellement, car les anciennes donnĂ©es doivent y rester, et en plus, une partie de ces anciennes donnĂ©es viendra s'y ajouter. Si vous avez pensĂ© Ă l'avance que les donnĂ©es devaient ĂȘtre resharded et que vous avez de la place, alors cette mĂ©thode fonctionnera.
Comment clickhouse-copier est-il organisĂ© en interne ? Il divise tout le travail en un ensemble de tĂąches de traitement d'une partition d'une table sur un shard. Toutes ces tĂąches peuvent ĂȘtre exĂ©cutĂ©es en parallĂšle, et clickhouse-copier peut ĂȘtre lancĂ© sur diffĂ©rentes machines en plusieurs instances, mais ce qu'il fait pour une partition, c'est rien d'autre qu'un insert select. Les donnĂ©es sont lues, dĂ©compressĂ©es, repartitionnĂ©es, puis Ă nouveau compressĂ©es, enregistrĂ©es quelque part, rĂ©organisĂ©es. C'est une solution plus lourde.
Vous aviez un projet pilote appelé reshaping. Qu'en est-il ?
Vous aviez encore en 2017 un projet pilote appelĂ© resharding. Il y a mĂȘme une option dans ClickHouse. Je comprends que cela nâa pas dĂ©collĂ©. Pouvez-vous expliquer pourquoi cela s'est produit ? Il semble que ce soit trĂšs pertinent.
Tout le problÚme est que lors de la nécessité de resharder des données sur place, une synchronisation trÚs complexe est requise pour le faire de maniÚre atomique. Lorsque nous avons commencé à examiner comment cette synchronisation était organisée, il est devenu clair qu'il y avait des problÚmes fondamentaux. Et ces problÚmes fondamentaux ne sont pas uniquement théoriques, mais se sont immédiatement manifestés dans la pratique par le fait que l'on peut expliquer trÚs simplement - rien ne fonctionne.
Peut-on fusionner toutes les parties des données avant de les déplacer sur des disques lents ?
Une question sur le TTL avec lâoption dĂ©placer vers un disque lent dans le contexte des fusions. Y a-t-il un moyen, autre que par cron, de fusionner toutes les partitions en une seule avant de les dĂ©placer vers les disques lents ?
La réponse à la question de savoir s'il est possible de fusionner automatiquement tous les morceaux en un avant leur transfert est non. Il me semble qu'il n'est pas nécessaire de le faire. Il est possible de ne pas fusionner toutes les parties en une seule, mais simplement de compter sur le fait qu'elles seront transférées sur les disques lents automatiquement.
Nous avons deux critÚres pour le transfert. Le premier est basé sur le taux d'occupation. Si le niveau actuel de stockage a moins d'un certain pourcentage d'espace libre, nous choisissons un morceau et le transférons sur un stockage plus lent. En fait, ce n'est pas juste plus lent, mais le suivant - comme vous le configurez.
Le deuxiÚme critÚre est la taille. Il concerne le transfert de gros morceaux. Vous pouvez ajuster le seuil d'espace libre sur le disque rapide, et les données seront transférées automatiquement.
Comment passer à de nouvelles versions de ClickHouse si je n'ai pas la possibilité de vérifier la compatibilité à l'avance ?
Ce sujet est réguliÚrement discuté , en tenant compte des différentes versions, et pourtant. à quel point est-il sûr de mettre à jour de la version 19.11 à 19.16 et, par exemple, de 19.16 à 20.3 ? Comment mieux passer aux nouvelles versions sans avoir la possibilité de vérifier la compatibilité dans un bac à sable à l'avance ?
Il y a plusieurs rÚgles « d'or ». La premiÚre est . Il est long, mais il contient des points spécifiques sur les changements incompatibles. Ne considérez pas ces points comme des drapeaux rouges. En général, ce sont de petites incompatibilités liées à certaines fonctionnalités marginales qui, trÚs probablement, ne vous concernent pas.
DeuxiĂšme rĂšgle - si vous n'avez pas la possibilitĂ© de vĂ©rifier la compatibilitĂ© dans un bac Ă sable, et que vous souhaitez mettre Ă jour directement en production, la recommandation est de ne pas le faire. CrĂ©ez d'abord un bac Ă sable et vĂ©rifiez. S'il n'y a pas d'environnement de test, alors vous n'ĂȘtes probablement pas une trĂšs grande entreprise, donc vous pouvez copier une partie des donnĂ©es sur votre ordinateur portable et vĂ©rifier que tout fonctionne correctement. Vous pouvez mĂȘme lancer plusieurs rĂ©pliques localement sur votre machine. Ou vous pouvez mettre en place une nouvelle version Ă proximitĂ© et y importer une partie des donnĂ©es - en d'autres termes, crĂ©er un environnement de test improvisĂ©.
Une autre rÚgle est de ne pas mettre à jour pendant une semaine aprÚs la sortie de la version en raison de la chasse aux bugs en production et des corrections rapides qui s'ensuivent. Comprenons la numérotation des versions ClickHouse pour ne pas nous perdre.
Il existe une version 20.3.4. Le chiffre 20 dĂ©signe l'annĂ©e de sortie â 2020. D'un point de vue technique, cela n'a aucune importance, donc nous n'y prĂȘterons pas attention. Ensuite, 20.3. Le deuxiĂšme chiffre â dans ce cas 3 â augmente chaque fois que nous publions une version avec de nouvelles fonctionnalitĂ©s. Si nous souhaitons ajouter une fonctionnalitĂ© Ă ClickHouse, nous sommes obligĂ©s d'augmenter ce chiffre. Ainsi, dans la version 20.4, ClickHouse fonctionnera encore mieux. Le troisiĂšme chiffre â 20.3.4. Ici, 4 indique le nombre de versions de correction oĂč nous n'avons pas ajoutĂ© de nouvelles fonctionnalitĂ©s, mais avons corrigĂ© certains bogues. Et 4 signifie que nous avons fait cela quatre fois.
Il ne faut pas penser que c'est quelque chose de terrible. En général, un utilisateur peut installer la version la plus récente et elle fonctionnera sans problÚme avec un temps de fonctionnement d'un an. Mais imaginez que dans une fonction de traitement de bitmaps, ajoutée par nos camarades chinois, un serveur plante à cause d'arguments incorrects. Nous devons corriger cela. Nous publierons une nouvelle version de correction, et ClickHouse deviendra plus stable.
Si vous avez ClickHouse en production, et qu'une nouvelle version de ClickHouse avec des fonctionnalitĂ©s supplĂ©mentaires sort â par exemple, 20.4.1 â n'ayez pas hĂąte de l'installer en production le premier jour. Ă quoi cela sert-il vraiment ? Si vous n'utilisez pas encore ClickHouse, vous pouvez l'installer, et tout ira probablement bien. Mais si ClickHouse fonctionne dĂ©jĂ de maniĂšre stable, suivez les mises Ă jour et les corrections â quels problĂšmes nous avons rĂ©solus.
Kirill Shvakov : Je souhaite ajouter quelques Ă©lĂ©ments concernant les environnements de test. Beaucoup craignent les environnements de test et pensent que si vous avez un trĂšs grand cluster ClickHouse, l'environnement de test doit ĂȘtre au moins aussi grand ou dix fois plus petit. C'est tout Ă fait faux.
Je peux partager mon expĂ©rience. J'ai un projet qui utilise ClickHouse. Notre environnement de test pour cela est une petite machine virtuelle chez Hetzner pour vingt euros, oĂč tout est dĂ©ployĂ©. Pour cela, nous avons une automatisation complĂšte avec Ansible, donc il n'y a pratiquement aucune diffĂ©rence entre dĂ©ployer sur des serveurs physiques ou simplement dans des machines virtuelles.
Que peut-on faire ? Ce serait bien d'ajouter un exemple dans la documentation de ClickHouse sur la maniĂšre de dĂ©ployer un petit cluster chez soi â en Docker, en LXC, ou Ă©ventuellement de crĂ©er un playbook Ansible, car chaque personne a des dĂ©ploiements diffĂ©rents. Cela simplifierait beaucoup de choses. Quand tu peux dĂ©ployer un cluster en cinq minutes, c'est bien plus facile de comprendre certains aspects. C'est beaucoup plus pratique, car aller en production avec une version que tu n'as pas testĂ©e â c'est un chemin sans retour. Parfois ça fonctionne, parfois non. Donc compter sur le succĂšs â c'est risquĂ©.
Maxim Kotyakov, ingĂ©nieur backend senior chez Avito : Je vais ajouter quelques Ă©lĂ©ments sur les environnements de test liĂ©s aux problĂšmes des grandes entreprises. Nous avons un cluster ClickHouse de validation complet, qui est une copie exacte des schĂ©mas de donnĂ©es et des configurations de notre production. Ce cluster est dĂ©ployĂ© dans des conteneurs assez modestes avec un minimum de ressources. Nous y Ă©crivons un certain pourcentage de donnĂ©es de production, car nous avons la possibilitĂ© de rĂ©pliquer le flux dans Kafka. Tout est synchronisĂ© et scalĂ© â tant en termes de puissance que de flux, et, en thĂ©orie, dans des conditions similaires, il devrait se comporter comme la production selon les mĂ©triques. Tout ce qui est potentiellement explosif passe d'abord sur cette plateforme et y reste quelques jours pour maturation. Mais Ă©videmment, cette solution est coĂ»teuse, lourde et avec des coĂ»ts non nĂ©gligeables de maintenance.
Alexey Milovidov: Je vais parler de l'environnement de test de nos amis de Yandex.Metrica. Un cluster avait plus de 600 serveurs, un autre en avait 360, et il y a aussi un troisiÚme cluster et plusieurs autres. L'environnement de test pour l'un d'eux consiste en deux shards avec deux répliques chacun. Pourquoi deux shards ? Pour avoir plus d'un shard. Et les répliques également pour assurer la redondance. Juste un minimum que l'on peut se permettre.
Cet environnement de test permet de vĂ©rifier le bon fonctionnement des requĂȘtes et de s'assurer que rien de majeur n'est dĂ©faillant. Mais il arrive souvent que des problĂšmes d'un autre type surviennent, quand tout fonctionne, mais qu'il y a des petites variations avec la charge.
Voici un exemple. Nous avons dĂ©cidĂ© d'installer une nouvelle version de ClickHouse. Elle a Ă©tĂ© mise sur l'environnement de test, les tests automatisĂ©s de Yandex.Metrica ont Ă©tĂ© effectuĂ©s, comparant les donnĂ©es de l'ancienne version Ă celles de la nouvelle, en passant par tout le pipeline. Et bien sĂ»r, les tests de notre CI Ă©taient tous verts. Sinon, nous n'aurions mĂȘme pas proposĂ© cette version.
Tout se passe bien. Nous commençons Ă dĂ©ployer en production. Je reçois un message indiquant que la charge sur les graphiques a augmentĂ© plusieurs fois. Nous revenons Ă la version prĂ©cĂ©dente. Je regarde le graphique et je vois : la charge a effectivement augmentĂ© plusieurs fois pendant le dĂ©ploiement, puis elle a diminuĂ© lorsque nous avons effectuĂ© le retour arriĂšre. Ensuite, nous avons commencĂ© Ă revenir Ă la version prĂ©cĂ©dente. Et la charge a Ă©galement augmentĂ© de la mĂȘme maniĂšre et a de nouveau chutĂ©. Donc, la conclusion est que la charge a augmentĂ© en lien avec le dĂ©ploiement, rien d'Ă©tonnant.
Par la suite, il a Ă©tĂ© difficile de convaincre mes collĂšgues de finalement installer la nouvelle version. Je dis : « Tout va bien, dĂ©ployez-la. Croisez les doigts, tout va fonctionner. Actuellement, la charge a augmentĂ© sur les graphiques, mais tout va bien. Tenez bon ». En gros, nous avons fait ça, et voilĂ â la version est mise en production. Mais presque Ă chaque dĂ©ploiement, des problĂšmes similaires surgissent.
Kill query devrait tuer les requĂȘtes, mais ce n'est pas le cas. Pourquoi ?
Un utilisateur est venu me voir, un analyste, et a créé une requĂȘte qui a mis mon cluster ClickHouse Ă l'arrĂȘt. Une nĆud ou le cluster entier â selon la rĂ©plique ou le shard oĂč la requĂȘte est tombĂ©e. Je vois que toutes les ressources CPU de ce serveur sont Ă leur maximum, tout est rouge. Cependant, ClickHouse rĂ©pond aux requĂȘtes. Et j'Ă©cris : « Montre-moi, s'il te plaĂźt, la liste des processus, quelle requĂȘte a engendrĂ© cette folie ».
Je trouve cette requĂȘte et je lui envoie un kill. Et je vois que rien ne se passe. Mon serveur est Ă son maximum, ClickHouse me renvoie encore quelques commandes, montre que le serveur est vivant, et tout va bien. Mais j'ai une dĂ©gradation dans toutes les requĂȘtes utilisateurs, la dĂ©gradation commence aussi pour l'Ă©criture dans ClickHouse, et ma commande de kill ne fonctionne pas. Pourquoi ? Je pensais que le kill devait arrĂȘter les requĂȘtes, mais ce n'est pas le cas.
La rĂ©ponse va ĂȘtre plutĂŽt Ă©trange. Le fait est que le kill ne tue pas les requĂȘtes.
Le kill Ă©tablit un petit drapeau intitulĂ© « je veux que cette requĂȘte soit tuĂ©e ». Et la requĂȘte, lorsqu'elle traite chaque bloc, vĂ©rifie ce drapeau. Si il est activĂ©, la requĂȘte s'arrĂȘte. Donc, personne ne tue la requĂȘte, elle doit vĂ©rifier et s'arrĂȘter toute seule. Et cela doit fonctionner dans tous les cas oĂč la requĂȘte est en train de traiter des blocs de donnĂ©es. Elle traitera le prochain bloc de donnĂ©es, vĂ©rifiera le drapeau et s'arrĂȘtera.
Cela ne fonctionne pas dans les cas oĂč la requĂȘte est bloquĂ©e pour une certaine opĂ©ration. Cependant, il est peu probable que ce soit votre cas, car, d'aprĂšs vos dires, cela utilise beaucoup de ressources serveur. Il est possible que cela ne fonctionne pas pour un tri externe et encore d'autres dĂ©tails. Mais en gĂ©nĂ©ral, cela ne devrait pas se produire, c'est un bug. La seule chose que je peux conseiller, c'est de mettre Ă jour ClickHouse.
Comment calculer le temps de réponse sous charge de lecture ?
Il y a une table qui stocke des agrĂ©gats par item â divers compteurs. Le nombre de lignes est d'environ cent millions. Peut-on s'attendre Ă un temps de rĂ©ponse prĂ©visible si l'on injecte 1K RPS avec 1K items ?
D'aprĂšs le contexte, il s'agit d'une charge de lecture, car il n'y a aucun problĂšme d'Ă©criture â on peut insĂ©rer autant de milliers, voire des centaines de milliers, et parfois plusieurs millions de lignes.
Les requĂȘtes de lecture sont trĂšs variĂ©es. Dans un select 1, ClickHouse peut exĂ©cuter environ des dizaines de milliers de requĂȘtes par seconde, donc mĂȘme des requĂȘtes pour une seule clĂ© nĂ©cessiteront certaines ressources. Et ces requĂȘtes ponctuelles seront plus complexes que dans des bases de donnĂ©es de type key-value, car pour chaque lecture, il faut lire un bloc de donnĂ©es par index. L'index ne pointe pas vers chaque enregistrement, mais vers chaque plage. Cela signifie qu'il faudra lire toute la plage - cela reprĂ©sente 8192 lignes par dĂ©faut. Et il faudra dĂ©compresser un bloc de donnĂ©es compressĂ© de 64 Ko Ă 1 Mo. En gĂ©nĂ©ral, de telles requĂȘtes ponctuelles prennent quelques millisecondes. Mais c'est la version la plus simple.
Essayons de faire une simple arithmĂ©tique. Si l'on multiplie quelques millisecondes par mille, cela donne quelques secondes. Comme si maintenir mille requĂȘtes par seconde n'Ă©tait pas possible, mais en rĂ©alitĂ© c'est faisable, car nous avons plusieurs cĆurs de processeur. Donc en principe, 1000 RPS, ClickHouse peut parfois le maintenir, mais pour des requĂȘtes courtes, en effet ponctuelles.
Si vous devez faire Ă©voluer le cluster ClickHouse en nombre de requĂȘtes simples, je recommande la solution la plus simple - augmenter le nombre de rĂ©pliques et envoyer des requĂȘtes Ă une rĂ©plique alĂ©atoire. Si une rĂ©plique peut supporter cinq cents requĂȘtes par seconde, ce qui est tout Ă fait rĂ©aliste, alors trois rĂ©pliques supporteront mille cinq cents.
Parfois, bien sûr, il est possible de configurer ClickHouse pour un maximum de lectures ponctuelles. Que faut-il pour cela ? PremiÚrement, réduire la granularité de l'index. Toutefois, il convient de la diminuer non pas à une unité, mais en fonction du nombre d'enregistrements dans l'index, qui sera de plusieurs millions ou dizaines de millions sur le serveur. Si la table contient cent millions de lignes, vous pouvez définir la granularité à 64.
Il est possible de rĂ©duire la taille du bloc compressĂ©. Pour cela, il y a des paramĂštres. min compress block size, max compress block size. Ils peuvent ĂȘtre rĂ©duits, les donnĂ©es rĂ©ajustĂ©es, et alors les requĂȘtes ponctuelles seront plus rapides. Mais tout de mĂȘme, ClickHouse n'est pas une base de donnĂ©es clĂ©-valeur. Un grand nombre de petites requĂȘtes est un antipattern de charge.
Kirill Shvakov : Je vais donner un conseil au cas oĂč il y aurait des compteurs ordinaires. C'est une situation assez standard lorsque ClickHouse stocke un certain compteur. J'ai un utilisateur, il vient d'un tel pays, avec un troisiĂšme champ, et il faut incrĂ©menter quelque chose. Vous prenez MySQL, vous crĂ©ez une clĂ© unique - dans MySQL, c'est une clĂ© dupliquĂ©e, et dans PostgreSQL, c'est un conflit - et vous ajoutez avec un plus. Cela fonctionnera beaucoup mieux.
Lorsque vous avez peu de données, il n'y a pas vraiment de sens à utiliser ClickHouse. Il existe des bases de données ordinaires qui s'en sortent trÚs bien.
Que peut-on ajuster dans ClickHouse pour avoir plus de données en cache ?
Imaginons une situation : sur les serveurs, il y a 256 Go de RAM, dans la routine quotidienne, ClickHouse utilise environ 60 à 80 Go, avec un pic allant jusqu'à 130. Que peut-on activer et ajuster pour avoir plus de données en cache et, par conséquent, moins d'accÚs au disque ?
En rÚgle générale, le cache des pages du systÚme d'exploitation s'acquitte bien de cette tùche. Si vous ouvrez simplement le top, que vous regardez là -bas cached ou free - il est aussi mentionné combien est mis en cache - vous pouvez constater que toute la mémoire libre est utilisée pour le cache. Et ces données seront lues non pas à partir du disque, mais de la RAM. à cet égard, je peux dire que le cache est utilisé efficacement, car ce sont les données compressées qui sont mises en cache.
Cependant, si vous souhaitez accĂ©lĂ©rer encore davantage certaines requĂȘtes simples, il existe la possibilitĂ© d'activer Ă l'intĂ©rieur de ClickHouse le cache des donnĂ©es non compressĂ©es. Cela s'appelle uncompressed cacheDans le fichier de configuration config.xml, vous devez dĂ©finir la taille du cache non compressĂ© Ă la valeur souhaitĂ©e - je recommande de ne pas dĂ©passer la moitiĂ© de la RAM libre, car le reste sera utilisĂ© pour le cache de page.
De plus, il existe deux paramĂštres au niveau de la requĂȘte. Le premier paramĂštre est utiliser le cache non compressĂ© - qui active son utilisation. Il est recommandĂ© de l'activer pour toutes les requĂȘtes, sauf pour celles lourdes qui peuvent lire toutes les donnĂ©es et ainsi vider ce cache. Et le second paramĂštre est quelque chose comme le nombre maximum de lignes Ă utiliser pour le cache. Il limite automatiquement les grandes requĂȘtes afin qu'elles contournent le cache.
Comment configurer storage_configuration pour un stockage en mémoire ?
Dans la nouvelle documentation de ClickHouse, j'ai trouvé une section relative . Dans la description, il y a un exemple avec un SSD rapide.
Il est intĂ©ressant de savoir comment configurer la mĂȘme chose avec de la mĂ©moire Ă chaud. Et une autre question. Comment fonctionne le select avec cette organisation de donnĂ©es, lira-t-il l'ensemble des donnĂ©es ou seulement celles qui sont sur le disque, et ces donnĂ©es sont-elles compressĂ©es en mĂ©moire ? Et comment fonctionne la section prewhere avec cette organisation de donnĂ©es ?
Ce paramÚtre influence le stockage des morceaux de données, et leur format ne change en rien.
Examinons cela plus en détail.
Il est possible de configurer le stockage des donnĂ©es en mĂ©moire. Tout ce qui est configurĂ© pour le disque, c'est son chemin. Vous crĂ©ez une partition tmpfs, qui est montĂ©e Ă un certain chemin dans le systĂšme de fichiers. Vous indiquez ce chemin comme celui de stockage des donnĂ©es pour la partition la plus chaude, y compris les morceaux de donnĂ©es qui commencent Ă ĂȘtre envoyĂ©s et Ă©crits, tout va bien.
Mais je ne recommande pas de le faire en raison de la faible fiabilitĂ©, bien que si vous avez au moins trois rĂ©pliques dans diffĂ©rents centres de donnĂ©es, cela peut ĂȘtre fait. Au cas oĂč, les donnĂ©es seront rĂ©cupĂ©rĂ©es. Imaginons qu'un serveur s'arrĂȘte subitement puis redĂ©marre. La partition est remontĂ©e Ă nouveau, mais elle est vide. Le serveur ClickHouse, au dĂ©marrage, voit que ces morceaux sont manquants, alors que selon les mĂ©tadonnĂ©es de ZooKeeper, ils devraient ĂȘtre prĂ©sents. Il vĂ©rifie sur quelles rĂ©pliques ils existent, les demande et les tĂ©lĂ©charge. Ainsi, les donnĂ©es seront rĂ©cupĂ©rĂ©es.
En ce sens, le stockage des donnĂ©es en RAM ne diffĂšre fondamentalement pas de leur stockage sur disque, car lorsqu'on Ă©crit des donnĂ©es sur disque, elles passent aussi d'abord par le cache de pages et sont physiquement enregistrĂ©es de maniĂšre diffĂ©rĂ©e. Cela dĂ©pend du mode de montage du systĂšme de fichiers. Mais pour ĂȘtre sĂ»r, je dirai que ClickHouse ne fait pas de fsync lors de l'insertion.
Les donnĂ©es en mĂ©moire sont stockĂ©es exactement dans le mĂȘme format que sur disque. La requĂȘte select sĂ©lectionne tout aussi prĂ©cisĂ©ment les morceaux Ă lire, choisissant les plages de donnĂ©es nĂ©cessaires, et les lit. Le prĂ©-filtrage fonctionne exactement de la mĂȘme maniĂšre, que les donnĂ©es soient en RAM ou sur disque.
Jusqu'Ă quel nombre de valeurs uniques Low Cardinality est-il efficace ?
Low Cardinality est astucieusement conçu. Il crĂ©e des dictionnaires de donnĂ©es, mais ceux-ci sont locaux. Tout d'abord, chaque morceau a ses propres dictionnaires, et ensuite, mĂȘme Ă l'intĂ©rieur d'un mĂȘme morceau, ils peuvent ĂȘtre diffĂ©rents pour chaque plage. Lorsque le nombre de valeurs uniques atteint un seuil - je crois que c'est un million - le dictionnaire est simplement mis de cĂŽtĂ© et un nouveau est créé.
La rĂ©ponse en gros : pour chaque plage locale - disons, pour chaque jour - jusqu'Ă environ un million de valeurs uniques, Low Cardinality est efficace. Au-delĂ , il y aura simplement un fallback, oĂč de nombreux dictionnaires diffĂ©rents seront utilisĂ©s au lieu d'un seul. Cela fonctionnera Ă peu prĂšs comme une colonne de type string, peut-ĂȘtre un peu moins efficacement, mais il n'y aura pas de dĂ©gradations de performance significatives.
Quelles sont les meilleures pratiques pour la recherche en texte intégral sur une table de cinq milliards de lignes ?
Il existe différentes options de réponse. La premiÚre est de dire que ClickHouse n'est pas un systÚme pour la recherche en texte intégral. Pour cela, il existe des systÚmes spéciaux, par exemple, et . Néanmoins, je rencontre de plus en plus de gens qui disent qu'ils passent d'Elasticsearch à ClickHouse.
Pourquoi cela se produit-il ? Ils expliquent que Elasticsearch ne parvient plus Ă gĂ©rer la charge Ă certains volumes, notamment en ce qui concerne la construction des index. Les index deviennent trop encombrants, et si l'on transfĂšre simplement les donnĂ©es dans ClickHouse, elles seront stockĂ©es de maniĂšre plusieurs fois plus efficace en termes de volume. De plus, les requĂȘtes de recherche Ă©taient souvent telles qu'il ne fallait pas trouver dans l'ensemble des donnĂ©es une phrase en tenant compte de la morphologie, mais des choses complĂštement diffĂ©rentes. Par exemple, trouver dans les logs des derniĂšres heures une sous-sĂ©quence de bytes.
Dans ce cas, vous crĂ©ez un index dans ClickHouse, dont le premier champ sera la date avec l'heure. Et la principale restriction des donnĂ©es sera prĂ©cisĂ©ment sur la plage de dates. Ă l'intĂ©rieur de la plage de dates choisie, il est gĂ©nĂ©ralement possible d'effectuer une recherche en texte intĂ©gral mĂȘme par mĂ©thode brute-force Ă l'aide de like. L'opĂ©rateur like dans ClickHouse est le plus efficace que vous puissiez trouver. Si vous en trouvez un meilleur, faites-le moi savoir.
Mais quand mĂȘme, like est un scan complet. Et le scan complet peut ĂȘtre lent non seulement en termes de CPU, mais aussi sur le disque. Si vous avez un teraoctet de donnĂ©es par jour, et que vous cherchez un mot en une journĂ©e, vous devrez scanner un teraoctet. Et il est sĂ»rement sur des disques durs ordinaires, et au final, ils seront chargĂ©s au point que vous ne pourrez pas accĂ©der Ă ce serveur par SSH.
Dans ce cas, je suis prĂȘt Ă proposer une autre petite astuce. C'est du genre expĂ©rimental - ça peut fonctionner, ou peut-ĂȘtre pas. ClickHouse dispose d'index en texte intĂ©gral sous forme de filtres de Bloom trigrammes. Nos collĂšgues de la sociĂ©tĂ© Arenadata ont dĂ©jĂ testĂ© ces index, et il s'avĂšre souvent qu'ils fonctionnent exactement comme prĂ©vu.
Pour les utiliser correctement, il faut bien comprendre comment ils fonctionnent : ce qu'est un filtre de Bloom trigramme et comment choisir sa taille. Je peux dire qu'ils aideront pour les requĂȘtes sur des phrases rares, des sous-chaĂźnes qui apparaissent rarement dans les donnĂ©es. Dans ce cas, des sous-intervalles seront sĂ©lectionnĂ©s par les index, et moins de donnĂ©es seront lues.
Récemment, ClickHouse a introduit des fonctions encore plus avancées pour la recherche en texte intégral. Tout d'abord, la recherche de plusieurs sous-chaßnes en une seule passe, y compris les variantes tenantes compte de la casse, sans tenir compte de la casse, avec le support de l'UTF-8 ou uniquement pour l'ASCII. Choisissez le plus efficace selon vos besoins.
Il est Ă©galement possible de rechercher plusieurs expressions rĂ©guliĂšres en une seule passe. Vous n'avez pas besoin d'Ă©crire X like une sous-chaĂźne ou X like une autre sous-chaĂźne. Ăcrivez tout d'un coup, et tout s'exĂ©cute de maniĂšre maximale et efficace.
TroisiÚmement, il y a désormais une recherche approximative des regex et une recherche approximate de sous-chaßnes. Si quelqu'un a écrit un mot avec une faute de frappe, il sera recherché selon la correspondance maximale.
Comment organiser l'accĂšs Ă ClickHouse pour un grand nombre d'utilisateurs ?
Expliquez comment organiser au mieux l'accĂšs pour un grand nombre de consommateurs et d'analystes. Comment former une file d'attente, prioriser les requĂȘtes max concurrent queries, et avec quels outils ?
Si le cluster est suffisamment grand, une bonne solution serait de dĂ©ployer deux autres serveurs, qui serviront de points d'entrĂ©e pour les analystes. C'est-Ă -dire ne pas donner accĂšs aux analystes Ă des shards spĂ©cifiques du cluster, mais simplement crĂ©er deux serveurs vides, sans donnĂ©es, et configurer les droits d'accĂšs dessus. En mĂȘme temps, les rĂ©glages des utilisateurs pour des requĂȘtes distribuĂ©es sont transfĂ©rĂ©s sur les serveurs distants. Vous configurez tout sur ces deux serveurs, et les rĂ©glages ont un effet sur tout le cluster.
En principe, ces serveurs sont sans donnĂ©es, mais la quantitĂ© de mĂ©moire vive sur eux est trĂšs importante pour l'exĂ©cution des requĂȘtes. Le disque peut Ă©galement ĂȘtre utilisĂ© pour des donnĂ©es temporaires, si l'agrĂ©gation externe ou le tri externe est activĂ©.
Il est important de vĂ©rifier les configurations liĂ©es Ă toutes les limites possibles. Si je vais maintenant sur le cluster « Yandex.Metrics » en tant qu'analyste et que je pose une requĂȘte select count from hits, je recevrai immĂ©diatement une exception indiquant que je ne peux pas exĂ©cuter la requĂȘte. Le nombre maximal de lignes que je suis autorisĂ© Ă scanner est de cent milliards, alors qu'il y a au total cinquante trillions dans une seule table du cluster. C'est la premiĂšre limitation.
Supposons que je retire la limite sur le nombre de lignes et que j'exĂ©cute la requĂȘte Ă nouveau. Dans ce cas, je verrai la prochaine exception - la configuration force index by date. Je ne peux pas exĂ©cuter la requĂȘte si je n'ai pas spĂ©cifiĂ© la plage de dates. Il ne faut pas compter sur le fait que les analystes vont la spĂ©cifier manuellement. Un cas typique est que la plage de dates est Ă©crite where event date between semaine. Et puis, simplement, une parenthĂšse a Ă©tĂ© mal placĂ©e, et au lieu de and, cela a donnĂ© or - or URL match. Si aucune limite n'est dĂ©finie, elle va scanner la colonne URL et dĂ©penser une tonne de ressources.
De plus, ClickHouse a deux rĂ©glages de prioritĂ©. Malheureusement, ils sont trĂšs primitifs. L'un s'appelle simplement prioritySi priority â 0 et que des requĂȘtes sont exĂ©cutĂ©es avec un certain prioritaire, mais qu'une requĂȘte avec un prioritaire ayant une valeur infĂ©rieure, ce qui signifie un prioritaire plus Ă©levĂ©, est en cours d'exĂ©cution, alors la requĂȘte avec une valeur de prioritaire plus Ă©levĂ©e, ce qui implique un prioritaire plus bas, est simplement suspendue et ne fonctionnera pas du tout pendant ce temps.
C'est un rĂ©glage trĂšs grossier et il n'est pas adaptĂ© aux cas oĂč il y a une charge constante sur le cluster. Mais si vous avez de courtes requĂȘtes impulsives qui sont importantes et que le cluster est principalement inactif, ce rĂ©glage peut convenir.
Le rĂ©glage des prioritĂ©s suivant s'appelle prioritĂ© des threads OS. Il fixe simplement pour tous les threads d'exĂ©cution de requĂȘte la valeur nice pour le planificateur Linux. Cela fonctionne moyennement, mais ça fonctionne quand mĂȘme. Si vous fixez la valeur nice la plus basse - elle est la plus Ă©levĂ©e en valeur, ce qui signifie le prioritaire le plus bas - et pour les requĂȘtes Ă haute prioritĂ©, vous fixez -19, le CPU consommera des requĂȘtes Ă faible prioritĂ© environ quatre fois moins que celles Ă haute prioritĂ©.
Il faut Ă©galement rĂ©gler le temps d'exĂ©cution maximum des requĂȘtes - disons, cinq minutes. La vitesse d'exĂ©cution minimale des requĂȘtes - c'est le plus cool. Ce rĂ©glage existe depuis longtemps et est nĂ©cessaire pour ne pas seulement affirmer que ClickHouse ne ralentit pas, mais pour y parvenir.
Imaginez que vous configurez : si une requĂȘte traite moins d'un million de lignes par seconde - cela ne peut pas ĂȘtre fait. Cela ternit notre bon nom, notre bonne base de donnĂ©es. Interdisons cela tout simplement. Il y a en fait deux rĂ©glages. L'un s'appelle vitesse d'exĂ©cution minimale â en lignes par seconde, et le second s'appelle le dĂ©lai avant vĂ©rification de la vitesse d'exĂ©cution minimale - par dĂ©faut quinze secondes. Donc quinze secondes c'est acceptable, et ensuite, si c'est lent, il suffit de lancer une exception - d'interrompre la requĂȘte.
Il faut Ă©galement rĂ©gler les quotas. ClickHouse a une fonctionnalitĂ© de quotas intĂ©grĂ©e qui calcule la consommation des ressources. Mais malheureusement, cela ne concerne pas les ressources matĂ©rielles comme le CPU, les disques, mais les ressources logiques - le nombre de requĂȘtes traitĂ©es, de lignes et d'octets lus. Et vous pouvez dĂ©finir, par exemple, un maximum de cent requĂȘtes en cinq minutes et mille requĂȘtes par heure.
Pourquoi est-ce important ? Parce qu'une partie des requĂȘtes analytiques sera exĂ©cutĂ©e manuellement directement depuis le client ClickHouse. Et tout ira bien. Mais si vous avez des analystes avancĂ©s dans votre entreprise, ils Ă©criront un script, et il peut y avoir une erreur dans le script. Et cette erreur conduira Ă ce que la requĂȘte s'exĂ©cute dans une boucle infinie. C'est ce dont il faut se protĂ©ger.
Peut-on envoyer les rĂ©sultats d'une requĂȘte Ă dix clients ?
Nous avons plusieurs utilisateurs qui aiment soumettre des requĂȘtes trĂšs lourdes en mĂȘme temps. La requĂȘte est grande, elle s'exĂ©cute gĂ©nĂ©ralement rapidement, mais Ă cause du grand nombre de requĂȘtes simultanĂ©es, cela devient trĂšs pĂ©nible. Est-il possible d'exĂ©cuter une mĂȘme requĂȘte qui a Ă©tĂ© envoyĂ©e dix fois de suite une fois et de donner le rĂ©sultat Ă dix clients ?
Le problĂšme est que nous n'avons pas de rĂ©sultats en cache ou de cache de donnĂ©es intermĂ©diaires. Il y a le cache de page du systĂšme d'exploitation, qui permet de ne pas lire les donnĂ©es depuis le disque Ă nouveau, mais malheureusement, les donnĂ©es devront tout de mĂȘme ĂȘtre dĂ©compressĂ©es, dĂ©sĂ©rialisĂ©es et retravaillĂ©es.
Nous aimerions Ă©viter cela d'une maniĂšre ou d'une autre, soit en mettant en cache les donnĂ©es intermĂ©diaires, soit en organisant des requĂȘtes similaires dans une sorte de queue et en ajoutant un cache des rĂ©sultats. Nous avons actuellement un pull request en dĂ©veloppement qui ajoute un cache des requĂȘtes, mais seulement pour les sous-requĂȘtes dans les sections in et join â c'est-Ă -dire que la solution n'est pas complĂšte.
NĂ©anmoins, nous rencontrons Ă©galement cette situation. Un exemple canonique en est les requĂȘtes avec pagination. Il existe un rapport qui comporte plusieurs pages, et il y a une requĂȘte limit 10. Puis la mĂȘme chose, mais limit 10,10. Ensuite, voici encore la page suivante. Et on se demande pourquoi nous calculons cela Ă chaque fois ? Mais pour l'instant, il n'y a pas de solution, et il est impossible d'y Ă©chapper.
Il existe une solution alternative qui s'installe en sidecar Ă cĂŽtĂ© de ClickHouse â .
Kirill Shvakov : ClickHouse Proxy a un limiteur de taux intĂ©grĂ© et un cache des rĂ©sultats. Il possĂšde de nombreuses configurations car un problĂšme similaire a Ă©tĂ© rĂ©solu. Le Proxy permet de limiter les requĂȘtes en les organisant dans une file d'attente, et de configurer la durĂ©e de vie du cache des requĂȘtes. Si les requĂȘtes Ă©taient effectivement identiques, le Proxy les renverra plusieurs fois, tout en interrogeant ClickHouse une seule fois.
Nginx dispose Ă©galement d'un cache dans sa version gratuite, et cela fonctionnera aussi. Nginx a mĂȘme des paramĂštres pour gĂ©rer les requĂȘtes simultanĂ©es, en ralentissant les autres tant qu'une n'est pas exĂ©cutĂ©e. Cependant, dans ClickHouse Proxy, la configuration est bien meilleure. Elle a Ă©tĂ© conçue spĂ©cifiquement pour ClickHouse et pour ces types de requĂȘtes, donc elle est plus adaptĂ©e. De plus, son installation est simple.
Comment gérer les opérations asynchrones et les vues matérialisées ?
Il y a un problÚme, c'est que les opérations avec le moteur de remplacement sont asynchrones : d'abord, les données sont écrites, puis le compactage a lieu. Si une table matérialisée avec des agrégats se trouve sous la table, alors des doublons y seront écrits. Et s'il n'y a pas de logique complexe, les données seront doublonnées. Que peut-on faire à ce sujet ?
Une solution évidente serait de mettre en place un déclencheur pour une certaine classe de vues matérialisées lors de l'opération asynchrone de compactage. Existe-t-il des "solutions miracles" ou des plans pour implémenter de telles fonctionnalités ?
Il convient de comprendre comment fonctionne la dé-duplication. Ce dont je vais parler maintenant n'est pas vraiment lié à la question, mais il est toujours bon de s'en souvenir.
Lors de l'insertion dans une table rĂ©pliquĂ©e, il y a une dĂ©-duplication de l'ensemble des blocs insĂ©rĂ©s. Si vous insĂ©rez Ă nouveau le mĂȘme bloc, contenant le mĂȘme nombre de lignes dans le mĂȘme ordre, les donnĂ©es seront dĂ©dupliquĂ©es. Vous recevrez âOkâ en rĂ©ponse Ă l'insertion, mais en rĂ©alitĂ©, une seule sĂ©rie de donnĂ©es sera enregistrĂ©e et elle ne sera pas doublĂ©e.
Cela est nĂ©cessaire pour la certitude. Si lors de l'insertion vous recevez âOkâ, cela signifie que vos donnĂ©es ont Ă©tĂ© insĂ©rĂ©es. Si vous recevez une erreur de ClickHouse, cela signifie qu'elles n'ont pas Ă©tĂ© insĂ©rĂ©es et que vous devez rĂ©pĂ©ter l'insertion. Mais si la connexion a Ă©tĂ© interrompue pendant l'insertion, vous ne savez pas si les donnĂ©es ont Ă©tĂ© insĂ©rĂ©es ou non. La seule option est de rĂ©pĂ©ter l'insertion. Si les donnĂ©es ont rĂ©ellement Ă©tĂ© insĂ©rĂ©es et que vous les rĂ©insĂ©rez, une dĂ©-duplication des blocs se produira. Cela est nĂ©cessaire pour Ă©viter les doublons.
Il est également important de comprendre comment cela fonctionne pour les vues matérialisées. Si les données ont été dédupliquées lors de l'insertion dans la table principale, alors elles ne seront également pas envoyées vers la vue matérialisée.
Maintenant, concernant la question. Vous avez une situation plus complexe, car vous enregistrez des duplicats de lignes individuelles. C'est-à -dire que ce n'est pas un ensemble complet qui est dupliqué, mais bien des lignes spécifiques, et elles sont agrégées en arriÚre-plan. En effet, les données seront agrégées dans la table principale, tandis que les vues matérialisées recevront les données non agrégées, et lors des fusions, rien ne se passera avec les vues matérialisées. Parce qu'une vue matérialisée n'est rien d'autre qu'un déclencheur sur insert. Dans d'autres opérations, rien de supplémentaire ne se produit avec elle.
Et je ne peux pas vraiment vous rĂ©jouir ici. Il faut seulement chercher une solution spĂ©cifique pour ce cas. Par exemple, peut-on Ă©galement effectuer un remplacement dans la vue matĂ©rialisĂ©e, et peut-ĂȘtre que le moyen de dĂ©-duplication fonctionnera ainsi. Mais malheureusement, ce n'est pas toujours le cas. Si elle est agrĂ©gative, cela ne fonctionnera pas.
Kirill Shvakov : Nous aussi, nous avions notre part de bricolage autrefois. Il y avait un problĂšme avec l'affichage des publicitĂ©s, et il y a certaines donnĂ©es que nous pouvons afficher en temps rĂ©el â ce ne sont que des affichages. Ils ne se dupliquent que rarement, mais si cela se produit, nous les agrĂ©gerons tout de mĂȘme ensuite. Et il y avait des Ă©lĂ©ments qui ne doivent pas ĂȘtre dupliquĂ©s â les clics et toute cette histoire. Mais nous voulions tout de mĂȘme les afficher presque immĂ©diatement.
Comment les vues matĂ©rialisĂ©es ont-elles Ă©tĂ© faites ? Il y avait des vues oĂč l'on Ă©crit directement â les donnĂ©es brutes sont enregistrĂ©es, et les rĂ©sultats sont Ă©crits dans les vues. Ă un certain moment, les donnĂ©es ne sont pas trĂšs correctes, elles se dupliquent, etc. Et il y a une deuxiĂšme partie de la table, oĂč elles apparaissent exactement comme les vues matĂ©rialisĂ©es, c'est-Ă -dire qu'elles sont absolument identiques en structure. De temps en temps, nous recalculons les donnĂ©es, comptons les donnĂ©es sans duplications, et les Ă©crivons dans ces tables.
Nous sommes passĂ©s par l'API â cela ne fonctionnera pas manuellement dans ClickHouse. Et l'API vĂ©rifie : quand j'ai la date du dernier ajout dans la table, oĂč les donnĂ©es sont dĂ©jĂ garanties comme correctes, et elle effectue une requĂȘte sur une table et sur une autre. D'une table, elle sĂ©lectionne jusqu'Ă un certain moment, et de l'autre, elle ajoute ce qui n'a pas encore Ă©tĂ© comptĂ©. Et cela fonctionne, mais pas avec les seules mĂ©thodes de ClickHouse.
Si vous avez une API â pour les analystes, pour les utilisateurs â c'est en principe une option. Vous effectuez toujours des calculs, vous recalculez toujours. Cela peut se faire une fois par jour ou Ă un autre moment. Vous choisissez vous-mĂȘme la plage qui ne vous est pas nĂ©cessaire et qui n'est pas critique.
Il y a beaucoup de logs dans ClickHouse. Comment puis-je voir tout ce qui se passe avec le serveur, en temps réel ?
ClickHouse possĂšde un trĂšs grand nombre de logs diffĂ©rents, et ce nombre augmente. Dans les nouvelles versions, certains d'entre eux sont mĂȘme activĂ©s par dĂ©faut, tandis que dans les anciennes versions, il faut les activer lors de la mise Ă jour. NĂ©anmoins, ils sont de plus en plus nombreux. J'aimerais voir, en fin de compte, ce qui m'arrive actuellement avec le serveur, peut-ĂȘtre sur un tableau de bord consolidĂ©.
N'avez-vous pas dans votre Ă©quipe ClickHouse, ou dans les Ă©quipes de vos amis, des gens qui maintiennent une certaine fonctionnalitĂ© de tableaux de bord prĂȘts Ă l'emploi, qui afficheraient ces logs sous forme de produit dĂ©jĂ prĂȘt ? En fin de compte, regarder les logs dans ClickHouse est formidable. Mais ce serait vraiment gĂ©nial si cela Ă©tait dĂ©jĂ prĂ©parĂ© sous forme de tableau de bord. J'en profiterais beaucoup.
Des tableaux de bord existent, mais ils ne sont pas standardisĂ©s. Dans notre entreprise, environ 60 Ă©quipes utilisent ClickHouse, et le plus Ă©trange, c'est que beaucoup d'entre elles ont des tableaux de bord qu'elles ont créés elles-mĂȘmes, qui sont lĂ©gĂšrement diffĂ©rents. Certaines Ă©quipes utilisent une installation interne de « Yandex.Cloud ». Il y a quelques rapports prĂȘts Ă l'emploi, bien qu'ils ne soient pas tous nĂ©cessaires. D'autres en ont de leur cĂŽtĂ©.
Mes collĂšgues de « Metrics » ont leur propre tableau de bord dans Grafana, et j'ai le mien sur leur cluster. J'y regarde des trucs comme le cache hit pour le cache des enregistrements. Et c'est encore plus compliquĂ© car nous utilisons diffĂ©rents outils. Mon tableau de bord a Ă©tĂ© créé avec un outil trĂšs ancien appelĂ© Graphite-web. Il est totalement inesthĂ©tique. Et je l'utilise toujours, mĂȘme si Grafana serait probablement plus pratique et plus jolie.
Les Ă©lĂ©ments de base des tableaux de bord sont identiques. Ce sont les mĂ©triques systĂšme du cluster : CPU, mĂ©moire, disque, rĂ©seau. Les autres sont le nombre de requĂȘtes simultanĂ©es, le nombre de fusions simultanĂ©es, le nombre de requĂȘtes par seconde, le nombre maximum de morceaux pour les partitions des tables MergeTree, le retard de rĂ©plication, la taille de la file d'attente de rĂ©plication, le nombre de lignes insĂ©rĂ©es par seconde, le nombre de blocs insĂ©rĂ©s par seconde. C'est tout ce qui ne provient pas des logs, mais des mĂ©triques.
Vladimir Kolobaev: AlexeĂŻ, je voudrais faire quelques ajustements. Il y a Grafana. Grafana a une source de donnĂ©es qui est ClickHouse. Donc, je peux faire des requĂȘtes directement dans ClickHouse depuis Grafana. Dans ClickHouse, il y a une table de logs, elle est identique pour tout le monde. Je veux, en fin de compte, interroger cette table de logs dans Grafana et voir les requĂȘtes que mon serveur effectue. Ce serait super d'avoir un tel tableau de bord.
Je l'ai bricolĂ© moi-mĂȘme. Mais j'ai une question : si tout cela est standardisĂ©, et que Grafana est utilisĂ© par tout le monde, pourquoi n'y a-t-il pas de tableau de bord officiel chez « Yandex » ?
Kirill Shvakov : En rĂ©alitĂ©, la source de donnĂ©es qui se connecte Ă ClickHouse est actuellement soutenue par Altinity. Je veux juste pointer dans une direction sur laquelle se pencher et vers qui pousser. On peut leur demander, car « Yandex » dĂ©veloppe quand mĂȘme ClickHouse, et non pas l'histoire qui l'entoure. Altinity est la principale entreprise qui promeut actuellement ClickHouse. Ils ne vont pas l'abandonner, ils vont le soutenir. Parce que, en principe, pour tĂ©lĂ©charger un tableau de bord sur le site de Grafana, il suffit de s'inscrire et de le tĂ©lĂ©charger, il n'y a pas de problĂšme particulier.
Alexey Milovidov: Au cours de l'annĂ©e derniĂšre, ClickHouse a ajoutĂ© de nombreuses fonctionnalitĂ©s pour le profilage des requĂȘtes. Il y a des mĂ©triques pour chaque requĂȘte concernant l'utilisation des ressources. Et rĂ©cemment, un profileur de requĂȘtes encore plus bas niveau a Ă©tĂ© ajoutĂ©, pour voir oĂč chaque requĂȘte passe chaque milliseconde. Mais pour profiter de cette fonctionnalitĂ©, je dois ouvrir le client en ligne de commande et taper la requĂȘte que j'oublie constamment. Je l'ai sauvegardĂ©e quelque part et j'oublie toujours oĂč exactement.
J'aimerais qu'il y ait un outil qui affiche simplement - voici vos requĂȘtes lourdes, groupĂ©es par catĂ©gories de requĂȘtes. Je clique sur l'une d'elles et on me dit pourquoi elle est lourde. Actuellement, il n'existe pas de telle solution. Et c'est vraiment assez Ă©trange que, lorsque les gens me demandent : « Dites, existe-t-il des tableaux de bord prĂȘts Ă l'emploi pour Grafana ? », je rĂ©ponds : « Allez sur le site de Grafana, il y a la communautĂ© 'Tableaux de bord', et il y a un tableau de bord de Dimka, un tableau de bord de Kostyan. Je ne sais pas ce que c'est, je ne l'ai pas utilisĂ© moi-mĂȘme. »
Comment agir sur les fusions pour que le serveur ne tombe pas en OOM ?
J'ai un tableau avec une seule partition, c'est un ReplacingMergeTree. J'y écris des données depuis quatre ans. J'avais besoin de faire un alter et de supprimer certaines données.
Je l'ai fait, et pendant le traitement de cette requĂȘte, toute la mĂ©moire sur tous les serveurs du cluster a Ă©tĂ© consommĂ©e, et tous les serveurs du cluster sont tombĂ©s ensemble en OOM. Ensuite, ils se sont tous relevĂ©s, ont commencĂ© Ă effectuer la fusion de cette mĂȘme opĂ©ration, de ce bloc de donnĂ©es, et sont Ă nouveau tombĂ©s en OOM. Puis ils se sont relevĂ©s Ă nouveau et sont retombĂ©s. Et cette situation ne s'est pas arrĂȘtĂ©e.
Il s'est avĂ©rĂ© que c'Ă©tait en fait un bug que les gars ont corrigĂ©. C'est super, merci beaucoup. Mais il reste un goĂ»t amer. Et maintenant, quand je pense Ă faire une fusion dans le tableau, je me demande â pourquoi ne puis-je pas influencer d'une certaine maniĂšre ces fusions ? Par exemple, limiter leur consommation de mĂ©moire nĂ©cessaire, ou mĂȘme leur nombre, qui va traiter spĂ©cifiquement ce tableau.
J'ai un tableau qui s'appelle 'MĂ©triques', traite-le s'il te plaĂźt avec deux threads. Pas besoin de crĂ©er dix ou cinq fusions en parallĂšle, fais-le en deux. Je pense qu'avec deux j'aurai assez de mĂ©moire, mais pour en traiter dix, je pourrais ne pas en avoir suffisamment. Pourquoi cette peur persiste-t-elle ? Parce que le tableau grandit, et un jour je vais me retrouver dans une situation oĂč, non pas Ă cause d'un bug, mais parce que les donnĂ©es vont changer en si grand nombre que je n'aurai tout simplement pas assez de mĂ©moire sur le serveur. Et alors le serveur tombera en OOM lors de la fusion. De plus, je peux annuler la mutation, mais les fusions, elles, ne peuvent pas ĂȘtre annulĂ©es.
Vous savez, lors des fusions, le serveur ne tombera pas en OOM, car lors de la fusion, il n'utilise la mémoire qu'à partir d'une petite plage de données. Donc tout ira bien, peu importe la quantité de données.
Vladimir Kolobaev: D'accord. Il y a un point ici, aprĂšs avoir corrigĂ© le bug, j'ai tĂ©lĂ©chargĂ© la nouvelle version, et sur une autre table, plus petite, oĂč il y a beaucoup de partitions, j'ai effectuĂ© une opĂ©ration similaire. Et pendant la fusion, environ 100 Go de mĂ©moire vive ont Ă©tĂ© utilisĂ©s. J'avais 150 Go de mĂ©moire occupĂ©e, 100 Go ont Ă©tĂ© consommĂ©s, et il me reste une marge de 50 Go, donc je ne suis pas tombĂ© en OOM.
Qu'est-ce qui me protÚge en ce moment d'un OOM, si cela nécessite vraiment 100 Go de mémoire vive ? Que faire si, par hasard, la mémoire vive vient à manquer lors des fusions ?
Alexey Milovidov: Il y a un problĂšme, c'est que la consommation de mĂ©moire vive lors des fusions n'est pas limitĂ©e. Et le deuxiĂšme problĂšme est que si une fusion est programmĂ©e, elle doit ĂȘtre exĂ©cutĂ©e, car elle est enregistrĂ©e dans le journal de rĂ©plication. Le journal de rĂ©plication contient les actions nĂ©cessaires pour amener la rĂ©plique dans un Ă©tat cohĂ©rent. Si nous ne faisons pas les manipulations manuelles qui annuleront ce journal de rĂ©plication, la fusion devra ĂȘtre exĂ©cutĂ©e, que cela nous plaise ou non.
Bien sĂ»r, ce ne serait pas superflu d'avoir une limite de mĂ©moire vive qui protĂšge, 'au cas oĂč', contre l'OOM. Cela n'aidera pas la fusion Ă s'exĂ©cuter, elle recommencera, atteindra un certain seuil, lancera une exception, et recommencera â rien de bon ne sortira de tout cela. Mais en principe, il serait utile d'introduire cette limitation.
Comment va se dérouler le développement du pilote Golang pour ClickHouse ?
Le pilote Golang, écrit par Kirill Shvakov, est maintenant officiellement soutenu par l'équipe ClickHouse. Il , il est maintenant grand et authentique.
Une petite remarque. Il existe un entrepĂŽt de formes infinies, merveilleux et trĂšs apprĂ©ciĂ© de tous, qui est Vertica. Ils ont aussi leur propre pilote Python, soutenu par les dĂ©veloppeurs de Vertica. Il y a eu plusieurs fois oĂč les versions de l'entrepĂŽt et du pilote Ă©taient trĂšs diffĂ©rentes, et Ă un moment donnĂ©, le pilote cessait de fonctionner. Un deuxiĂšme point Ă mentionner. Il me semble que le support de ce pilote officiel est gĂ©rĂ© via un systĂšme de type « nippel » â vous leur Ă©crivez un problĂšme et il reste suspendu indĂ©finiment.
J'ai deux questions. Actuellement, le pilote Golang de Kirill est presque la mĂ©thode par dĂ©faut pour communiquer avec ClickHouse depuis Golang. Ă part quelques personnes qui utilisent encore lâinterface HTTP, parce quâelle leur plaĂźt. Comment le dĂ©veloppement de ce pilote se dĂ©roulera-t-il ? Sera-t-il synchronisĂ© avec des modifications majeures dans l'entrepĂŽt lui-mĂȘme ? Et quelle est la procĂ©dure de traitement des problĂšmes ?
Kirill Shvakov : PremiĂšrement, comment tout cela est organisĂ© sur le plan bureaucratique. Cet aspect nâa pas Ă©tĂ© discutĂ©, donc je nâai rien Ă rĂ©pondre.
Pour rĂ©pondre Ă la question concernant les problĂšmes, il est nĂ©cessaire de raconter l'histoire du pilote. J'ai travaillĂ© dans une entreprise oĂč il y avait beaucoup de donnĂ©es. C'Ă©tait un moteur publicitaire avec un Ă©norme nombre d'Ă©vĂ©nements Ă stocker quelque part. Ă un moment donnĂ©, ClickHouse est apparu. Nous y avons versĂ© des donnĂ©es, et au dĂ©but, tout allait bien, mais ensuite ClickHouse est tombĂ©. Ă ce moment-lĂ , nous avons dĂ©cidĂ© que cela ne nous convenait pas.
Un an plus tard, nous sommes revenus Ă l'idĂ©e d'utiliser ClickHouse, et nous devions trouver un moyen dâĂ©crire des donnĂ©es. L'introduction Ă©tait la suivante : le matĂ©riel Ă©tait trĂšs faible, les ressources Ă©taient limitĂ©es. Mais nous avons toujours travaillĂ© de cette maniĂšre, donc nous avons cherchĂ© du cĂŽtĂ© du protocole natif.
Puisque nous travaillions avec Go, il Ă©tait clair qu'un pilote pour Go Ă©tait nĂ©cessaire. J'y ai travaillĂ© presque Ă plein temps - c'Ă©tait ma tĂąche professionnelle. Jusqu'Ă un certain point, nous l'avons dĂ©veloppĂ©, et en principe, personne ne s'attendait Ă ce que quelqu'un d'autre lâutilise. Ensuite, CloudFlare est venu avec exactement le mĂȘme problĂšme, et pendant un certain temps, nous avons travaillĂ© trĂšs Ă©troitement avec eux, car ils avaient les mĂȘmes exigences. Nous avons fait cela Ă la fois dans ClickHouse lui-mĂȘme et dans le pilote.
Ă un moment donnĂ©, j'ai simplement cessĂ© de m'en occuper, car mon activitĂ© concernant ClickHouse et mon travail ont un peu changĂ©. C'est pourquoi les incidents ne sont pas rĂ©solus. PĂ©riodiquement, des gens comittent dans le dĂ©pĂŽt quand ils ont besoin de quelque chose. Ă ce moment-lĂ , je regarde les pull requests et parfois je corrige mĂȘme quelque chose moi-mĂȘme, mais cela arrive rarement.
J'aimerais revenir au driver. Il y a plusieurs années, quand tout cela a commencé, ClickHouse était différent et avait d'autres fonctionnalités. Maintenant, nous savons comment revoir le driver pour que ce soit bien. Si cela se réalise, la version 2 sera de toute façon incompatible à cause des divers hacks accumulés.
Je ne sais pas comment organiser cela. Je n'ai pas beaucoup de temps moi-mĂȘme. Si certaines personnes veulent peaufiner le driver, je pourrai les aider et leur expliquer quoi faire. Mais la participation active de Yandex dans le dĂ©veloppement du projet n'a pas encore Ă©tĂ© discutĂ©e.
Alexey Milovidov: En réalité, il n'y a pas encore de bureaucratie concernant ces drivers. La seule chose est qu'ils ont été intégrés dans une organisation officielle, c'est-à -dire que ce driver est reconnu comme une solution officielle par défaut pour Go. Il existe d'autres drivers, mais ils sont séparés.
Nous n'avons pas de développement interne pour ces drivers. La question est de savoir si nous pourrons embaucher une personne, pas spécifiquement pour ce driver, mais pour le développement de tous les drivers communautaires, ou si nous pourrons trouver quelqu'un à l'extérieur.
Le dictionnaire externe ne se charge pas aprÚs le redémarrage avec l'option lazy_load activée. Que faire?
Nous avons l'option lazy_load activée, et aprÚs le redémarrage du serveur, le dictionnaire ne se charge pas automatiquement. Il ne se charge qu'aprÚs qu'un utilisateur y ait accédé. Et à la premiÚre sollicitation, il renvoie une erreur. Y a-t-il un moyen d'automatiser le chargement des dictionnaires avec ClickHouse, ou devons-nous toujours contrÎler leur disponibilité pour éviter que les utilisateurs ne rencontrent des erreurs?
Il se peut que nous ayons une ancienne version de ClickHouse, c'est pourquoi le dictionnaire ne s'est pas chargé automatiquement. Est-ce possible?
Tout d'abord, les dictionnaires peuvent ĂȘtre chargĂ©s de force Ă l'aide de la requĂȘte system reload dictionaries. DeuxiĂšmement, concernant l'erreur â si le dictionnaire est dĂ©jĂ chargĂ©, les requĂȘtes fonctionneront sur les donnĂ©es qui ont Ă©tĂ© chargĂ©es. S'il n'a pas encore Ă©tĂ© chargĂ©, il se chargera pendant la requĂȘte.
Pour les dictionnaires lourds, ce n'est pas trĂšs pratique. Par exemple, il faut rĂ©cupĂ©rer un million de lignes depuis MySQL. Certains font une simple sĂ©lection, mais cette sĂ©lection attend justement ce million de lignes. Il y a deux solutions. La premiĂšre est de dĂ©sactiver lazy_load. La seconde est que lorsque le serveur se lĂšve, avant de lui appliquer la charge, faites system reload dictionary ou simplement exĂ©cutez une requĂȘte qui utilise le dictionnaire. Dans ce cas, le dictionnaire sera chargĂ©. Vous devez contrĂŽler vous-mĂȘme la disponibilitĂ© des dictionnaires avec le paramĂštre lazy_load activĂ©, car ClickHouse ne les recharge pas automatiquement.
Pour la derniÚre question, la réponse est soit que la version est ancienne, soit qu'il faut déboguer.
Comment gérer le fait que system reload dictionaries ne charge aucun des nombreux dictionnaires si au moins l'un d'eux échoue avec une erreur ?
Il y a aussi une question concernant system reload dictionaries. Nous avons deux dictionnaires : l'un ne se charge pas, l'autre se charge. Dans ce cas, system reload dictionaries ne recharge aucun dictionnaire, et il faut le recharger spécifiquement par son nom à l'aide de system reload dictionary. Est-ce également lié à la version de ClickHouse ?
Je suis heureux de l'annoncer. Ce comportement a changé. Cela signifie que si vous mettez à jour ClickHouse, cela changera aussi. Si le comportement actuel ne vous satisfait pas system reload dictionaries, mettez à jour, et espérons que cela s'améliorera.
Y a-t-il un moyen de configurer les identifiants dans la configuration de ClickHouse, mais sans les exposer en cas d'erreurs ?
La question suivante concerne les erreurs liées au dictionnaire, à savoir les identifiants de connexion. Nous avons inscrit les identifiants de connexion dans la configuration de ClickHouse pour le dictionnaire, et en cas d'erreur, nous recevons ces identifiants ainsi que le mot de passe en retour.
Nous avons résolu cette erreur en extrayant les identifiants dans la configuration du pilote ODBC. Existe-t-il un moyen de configurer les identifiants dans la configuration de ClickHouse sans les exposer lors des erreurs ?
La solution ici est effectivement d'indiquer ces credentials dans le fichier odbc.ini, et dans ClickHouse, d'indiquer uniquement le nom de la source de donnĂ©es ODBC. Pour les autres sources de dictionnaires, cela ne sera pas le cas â ni pour le dictionnaire avec MySQL, ni pour les autres vous ne devriez pas voir le mot de passe lors d'un message d'erreur. Pour l'ODBC, je vais aussi vĂ©rifier â s'il y a un tel cas, il suffit de l'enlever.
Bonus : fonds pour Zoom à partir de soirées
En cliquant sur l'image, pour les lecteurs les plus persistants, des fonds bonus Ă thĂšme de rĂ©unions s'ouvriront. Ăteignons le feu avec les mascottes des technologies Avito, tenons des rĂ©unions avec des collĂšgues dans la salle des administrateurs systĂšme ou un vieux club d'informatique, et faisons des rĂ©unions sous le pont sur fond de graffiti.
Source : habr.com
