ElasticSearch sur les stéroïdes avec les schémas Avro
Comment faire face à l’explosion des versions d’interface dans une configuration de grande entreprise
L’article suivant explique une approche pour utiliser les technologies modernes de stockage et de sérialisation des données pour découpler les composants et arrêter l’explosion des versions d’interface de service inhérentes aux applications de consommation de données à grande échelle d’une entreprise.
Étant responsable dans un grand institut financier d’un système de fournisseur de données très utilisé, je suis toujours confronté à des itérations de déploiement sans fin de nouvelles versions de service et à l’incapacité de plusieurs consommateurs de passer à la nouvelle version dans un délai décent. Il en résulte au fil du temps un paysage d’une multitude de versions parallèles fonctionnant pour un service.
Un mot d’avertissement: l’approche est basée sur une infrastructure de stockage de données NoSQL et, je suis parfaitement conscient que ce stockage de données peut ne pas convenir à tous les types d’applications d’entreprise. Néanmoins, il existe plus que suffisamment de cas d’utilisation qui conviendraient parfaitement à ce type d’architecture.
Notre tutoriel couvre le scénario suivant:
Nous avons un composant de service qui traite une entrée utilisateur fournie via une application de navigateur basée sur React pour conserver ses données dans un magasin de persistance basé sur le cluster ElasticSearch.
- (3): Le
ReactUI
envoie une charge utile de données JSON localisée (entrée utilisateur) auServiceComponent
- (4): Le
ServiceComponent
délocalise la charge utile des données JSON en remplaçant le texte localisé par des valeurs de code de référence et prépare un message binaire Avro (sérialisation) qui est ensuite envoyé auBackendComponent
- (5): Le
BackendComponent
désérialise le message binaire Avro et le transforme en message Avro JSON, puis le stocke dansElasticSearch Cluster
Avro Schema
Une caractéristique clé du message Avro est qu’il se décrit lui-même via son schéma Avro associé. Le schéma Avro est une définition basée sur JSON de la structure des messages.
Reportez-vous au schéma Avro simple ci-dessous.
L’exemple décrit déjà quelques spécificités du langage de définition de schéma Avro.
-
personid
etlastname
sont des attributs obligatoires de typelong
etstring
-
surname
est un attribut union, c’est-à-dire qu’il peut être soitnull
ou avoir une valeur de typestring
. Par défaut, sa valeur estnull
.
Les valeurs facultatives sont toujours exprimées sous forme d’unions, et pour être prêt pour une évolution transparente du schéma (plus d’informations plus loin), vous devez toujours définir une valeur par défaut pour les attributs facultatifs.
Analyseur de schéma Avro et générateur de liaisons client
Le schéma est utilisé par le sérialiseur et le désérialiseur Avro pour analyser un message binaire Avro (ou un message Avro JSON selon la configuration choisie) dans des objets d’accès aux données Java (DAO). Ces DAO peuvent être des classes Java à schéma typé fort génériques ou précompilées.
C’est-à-dire l’objectif de Maven generate-sources
génère une classe Person
qui a trois attributs personId
, lastName
et firstname
L’objet personne peut ensuite être instancié à partir d’un message binaire de ce type en utilisant l’analyseur Avro.
Pour être auto-descriptif, un message Avro peut être complété par le schéma lui-même ou une empreinte digitale de schéma.
L’approvisionnement du schéma complet JSON est généralement effectué dans des approches basées sur des fichiers, qui regroupent une grande quantité de messages Avro. Dans notre parcours d’interaction – un style de demande-réponse avec un seul message Avro – une telle approche serait trop lourde. Pour ce scénario, l’empreinte du schéma est la bonne approche.
Répertoire des empreintes digitales et des schémas Avro
L’empreinte digitale du schéma Avro est un identifiant unique au monde pour référencer le schéma correct dans un registre de schéma central.
Le résumé ci-dessous SchemaRegistry
La classe décrit les méthodes requises par un tel registre.
- La méthode
registerSchema
, permet à un expéditeur (éditeur) d’enregistrer le schéma Avro du message qu’il envoie au lecteur (consommateur). En tant que valeur de retour, l’empreinte digitale Avro sera retournée, ce qui identifie de manière unique ce schéma. Toute modification du schéma lui-même entraînera une nouvelle empreinte digitale. - L’empreinte digitale est calculée avec la méthode
getSchemaFingerprint
- La méthode
getSchema
renverra l’Avro JSON associé au passéfingerprint
C’est tout, avec un registre de schéma mondial établi qui peut être utilisé par les lecteurs ou les écrivains de messages Avro pour échanger une empreinte digitale de schéma pour le schéma JSON associé, vous êtes prêt à exploiter toute la puissance d’Avro.
Le didacticiel fournit deux implémentations d’un registre de schéma:
- une implémentation basée sur des fichiers pour des tests légers, ainsi qu’un
- Implémentation basée sur ElasticSearch (ES). Si vous avez un cluster ES productif dans votre entreprise instancié, vous pouvez facilement l’utiliser comme registre de schéma à l’échelle de votre entreprise en introduisant un index ES dédié.
- Des registres de schéma standard sont disponibles, en particulier dans le domaine Kafka, par exemple, le registre de schéma de Confluent Kafka produit. Mais nous le gardons aussi simple que possible et utilisons ElasticSearch, qui est utilisé comme magasin de données cible.
L’exemple ci-dessous montre le schéma enregistré d’ElasticSearch sous son empreinte digitale 8354639983941950121
dans l’index avroschema
. Tout écrivain ou lecteur de messages utilisera les empreintes digitales Avro pour référencer son schéma sous-jacent utilisé dans son traitement.
En utilisant ElasticSearch, vous obtiendrez immédiatement un référentiel central des définitions de schéma, qui peut être facilement amélioré avec des capacités de recherche et de requête utilisées par les analystes commerciaux, les concepteurs ou les développeurs pendant le temps de développement du système.
Vous vous trompez si vous pensez qu’il y a beaucoup de codage nécessaire pour implémenter un registre de schéma.
Ci-dessous, vous voyez le fonctionnement complet ElasticSearchSchemaRegistry
classe java.
ESPersistency Manager
Assez simple et compact. On pourrait argumenter maintenant ESPersistencyManager
classe cache la complexité (qui est utilisée et implémentée dans le cadre du didacticiel).
Eh bien pas vraiment, la classe est une couche ultra-légère autour Plaisanter, un client HTTP HTTP pour Elasticsearch. Alors qu’Elasticsearch fournit son propre client Java natif, Jest fournit une API plus fluide et une interface plus naturelle pour travailler. Intéressé par JEST, consultez Article du didacticiel de Blaedung.
Notre ESPersisencyManager
protège simplement nos cours de didacticiel contre les expositions directes de Jest. Une technique d’encapsulation était capable de remplacer le gestionnaire de persistance dans une future version.
Encore une fois très compact pour obtenir un schéma Avro persisté. Il est utile de mentionner que vous pouvez fournir à ElasticSearch votre propre clé primaire (dans ES appelé _id
). Dans notre tutoriel, nous utilisons l’empreinte unique globale comme identifiant principal dans ES, ce qui rend la recherche simple (voir capture d’écran ci-dessus). Il s’agit d’une fonctionnalité clé pour fournir votre clé primaire, en particulier lorsque vous utilisez ElasticSearch dans un scénario de réplication de données, où ES n’est que l’esclave d’un autre système maître, qui a déjà généré des clés primaires.
Comme vous pouvez l’imaginer, récupérer un objet JSON est encore plus simple. Jest fait le travail pour nous.
Séquence de démarrage du composant principal
Nous devrions maintenant avoir une assez bonne compréhension de ce qui doit être préparé et configuré par le composant Backend en utilisant notre approche.
Le diagramme ci-dessous décrit les étapes les plus importantes: