编程知识 cdmana.com

Un article vous amène à Zookeeper.

zookeeperConcepts de base

zookeeperEst un cadre de services de coordination distribués open source,Fournir des services cohérents pour les environnements distribués,Les scénarios d'application courants sont les suivants::Publier un abonnement,Avis d'initiative,Gestion des documents,Gestion des grappes,Verrouillage distribué et autres fonctions.zkSatisfait au moment de la conceptioncpDeux éléments,C'est - à - dire la cohérence et la tolérance aux défauts de partition.

zookeeperLa philosophie de conception de

Voici quelques exemples d'expériences passées.,Résumez - le simplement comme suit::
Cohérence
Comme le montre la figure ci - dessous,Une fois que tous les clients sont connectés à l'environnement Cluster,Peu importe l'accèszk- Oui.leaderLe rôle oufollowerRôle,ChaquezkLes données des noeuds sont les mêmes.Supposons un moment,zkLes données d'un noeud ont été modifiées,Ensuite, vous devez synchroniser les données de chaque noeud avant de pouvoir continuer à fournir la fonction de lecture externe du noeud.
Photos: https://uploader.shimo.im/f/0dRhY6ULCmrJZDn7.png

Tête.
Dans un environnement groupé,Il doit y en avoir un.leaderLe rôle de leader de Cluster.Une foisleaderRaccroche.,Il y aura de nouvelles élections.leader.

Arbre de données
zkLa structure arborescente est utilisée pour le stockage interne des données,C'est un peu comme la conception d'un système de fichiers,Les noeuds enfants stockés sous chaque noeud d'arbre peuvent être dans un état ordonné , Comme le montre la figure ci - dessous:
Insérer la description de l'image ici

zookeeperInformations de configuration internes pertinentes

Contenu du profil général
UtilisationzkLa version est3.4.14Version

# zookeeperUnités de base dans la configuration du temps (MS)
tickTime=2000
# AllowfollowerInitialiser la connexion àleaderDurée maximale,Il indiquetickTimeTemps multiple C'est - à - dire::initLimit*tickTime 
initLimit=10
# AllowfollowerAvecleaderDurée maximale de synchronisation des données,Il indiquetickTimeTemps multiple 
syncLimit=5
# Emplacement des données du noeud
dataDir=/Users/linhao/env/zookeeper/zk-data
# Numéro de port
clientPort=2181
# Nombre maximum de connexions simultanées
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
#Adresse du Journal
dataLogDir=/Users/linhao/env/zookeeper/zk-log

# Nombre d'instantanés de données enregistrés,Les autres seront effacés
autopurge.snapRetainCount=3
#Déclenchement automatique de l'intervalle de tâches de nettoyage,Heures.Par défaut0,Indique que le nettoyage n'est pas automatique.
autopurge.purgeInterval=1

Ordre interne

DémarragezookeeperScript

sh ./zkServer.sh start

Instructions du serveur de connexion

sh ./zkCli.sh

Ajout, suppression, modification et recherche de noeuds

ls /  Interroger tous les noeuds racine

ls /idea RequêteideaContenu sous le noeud

delete /idea SupprimerideaNoeud

delete /idea/node-1 SupprimerideaSous le noeudnode-1Sous - noeud

create /idea/node-2 "v1" Créationidea/node-2Noeud Et écrirev1Valeur

get /idea/node-1 Obtenir les noeuds associés

Type de noeud

Noeud persistant
Le noeud créé par défaut est le type de persistance

create  /node ""

Noeud temporaire
Inzookeeper3.4Dans la version,Les exceptions suivantes peuvent se produire lors de la création d'un noeud temporaire:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
	at org.apache.zookeeper.ZooKeeperMain.processZKCmd(ZooKeeperMain.java:707)

La commande d'exécution correcte du noeud temporaire est :

create -e /temp ""

Noeud d'ordre persistant

create -s /seq-node ""

Après avoir exécuté la directive plusieurs fois, vous pouvez voir ce qui suit:

[zk: localhost:2181(CONNECTED) 4] ls /
[dubbo, seq-node0000000010, ietty, zookeeper, idea]
[zk: localhost:2181(CONNECTED) 5] create -s /seq-node ""
Created /seq-node0000000011
[zk: localhost:2181(CONNECTED) 6] create -s /seq-node ""
Created /seq-node0000000012
[zk: localhost:2181(CONNECTED) 7] create -s /seq-node ""
Created /seq-node0000000013
[zk: localhost:2181(CONNECTED) 8] create -s /seq-node ""
Created /seq-node0000000014

Plusieurs données de noeud séquentiel ont été créées sous le noeud

Noeud de séquence temporaire

create -e -s /seq-temp-node ""

Afficher les informations du noeud

statLa commande vous permet de visualiser les différents attributs sous le noeud
[zk: localhost:2181(CONNECTED) 12] stat /idea
//Créer une transaction pour un noeudid
cZxid = 0x1bd6
//Temps de création du noeud
ctime = Sun Nov 08 22:50:57 CST 2020
//Modifier la transaction du noeudid
mZxid = 0x1bd6
//Dernière modification
mtime = Sun Nov 08 22:50:57 CST 2020
//Transaction pour le changement de noeud enfantID
pZxid = 0x1bdb
//Nombre de modifications apportées aux noeuds enfants
cversion = 4
dataVersion = 0
//Version de permission
aclVersion = 0
ephemeralOwner = 0x0
//Longueur des données
dataLength = 12
//Nombre de sous - noeuds au premier niveau Ne contient pas de sous - noeuds
numChildren = 2

aclParamètres de permission
ACLNom completAccess Control List(Liste de contrôle d'accès),Droits d'accès pour contrôler les ressources.ZooKeeperUtiliserACLPour contrôlerznodePrévention.Basé surschemepermissionContrôle de l'Autorité.schemeIndique le mode d'autorisation、idValeur correspondante du mode、permissionC'est - à - dire ajouter, supprimer et modifier des bits d'autorisation spécifiques.
schemeModèle de certification

Programme Description
world Mode ouvert,worldIndique que le monde entier est accessible(C'est le paramètre par défaut)
ip ipMode,Client qualifiéIPQuestions préventives
auth Mode d'authentification par mot de passe de l'utilisateur,L'authentification ne peut être évitée que si elle est ajoutée à la session
digest AvecauthSimilaire,La différence est queauthUtiliser un mot de passe en texte clair,Etdigest Avecsha-1+base64Mot de passe chiffré.Dans la pratiquedigest Plus fréquent.

permissionBits de permission

Bits de permission Autorité Description
c CREATE Peut créer des noeuds enfants
d DELETE Les noeuds enfants peuvent être supprimés(Noeud de niveau inférieur seulement)
r READ Peut lire les données du noeud et afficher la liste des noeuds enfants
w WRITE Les données du noeud peuvent être définies
a ADMIN Vous pouvez définir les permissions de la liste de contrôle d'accès des noeuds

acl Commandes connexes

Les ordres Description
getAcl getAcl
setAcl setAcl
addauth addauth

world Exemple de permission Syntaxe: setAcl world:anyone:<Bits de permission> Note::worldEn modeanyoneEst une valeur unique,Représente tout le monde
Afficher les permissions par défaut du noeud:

#Créer un noeud
create -e /testAcl
#Afficher les permissions du noeud
getAcl /testAcl
#Représentation par défaut des permissions retournées ,Le propriétaire a toutes les permissions.
'world,'anyone: cdrwa
Modifier les permissions par défaut à Lire et écrire
#Set torwAutorité 
setAcl /testAcl world:anyone:rw
# Peut être lu normalement
get /testAcl
# Impossible de créer un noeud enfant normalement
create -e /testAcl/t "hi"
# Renvoie une exception sans permission
Authentication is not valid : /testAcl/t

zookeeperCluster
Il est recommandé d'avoir au moins trois serveurs .

Dans les deux cas, il y aura des élections.:
1.Initialisation du noeud de service
2.Ou plus de la moitié des noeuds ne peuvent pasleaderPour établir une connexion

Dans le clusterzkLes machines ont des fonctions de lecture et d'écriture.

zkÉlection des groupes

Avant d'expliquer les élections,Nous devons d'abord comprendre ce qu'estzxid.
InzkDans les données du noeud pour,Chaque fois qu'un changement de données se produit, il y a un fluxidFaire des enregistrements incrémentaux,C'estidCe que nous appelonszxid,De différentes machineszxidÇa pourrait être différent,Plus la taille est grande, plus les données actuelles sont récentes..En fait, chaquezkLes noeuds ont deuxid,Respectivement.czxidEtmzxid.L'abréviation du nom peut être traduite comme suit::
czxid:Lors de la création du noeudxid.
mzxid:Lors de la modification des données du noeudxid.

Réflexion générale sur le vote

Votez pour vous - même au premier tour.
Deuxième tour de scrutinzxidNoeud adjacent plus grand que lui - même Si plus de la moitié des voix sont exprimées,Clôture des élections.

Supposons qu'il y ait3Machine à voter,Respectivement.1,2,3Machine No.,La séquence de démarrage est1,2,3

Premier tour de scrutin
1La machine n° 1 a voté pour1Moi - même.
2La machine n° 1 a voté pour2Moi - même.
3La machine n° 1 a voté pour3Moi - même.

Deuxième tour de scrutin
1Machine no 1id< 2Machine no 1id <3Machine no 1id
1La machine n° 1 a voté pour2Machine No.,En ce moment2Plus de la moitié du nombre total de machines,Alors...2No.leader
2Votez pour3Machine No.,Parce que maintenant2La machine n° 1 est déjàleaderC'est,Alors...3La machine n° 1 n'est toujours disponible qu'avec1Machine no 1 maintenue ensemblefollowerRôle.

Donc après un tour d'élection,,2La machine n°1 est élue.leader

Comment assurer la synchronisation de l'état des données des noeuds maître - esclave

ZABAccord
InzkEn grappes,Garantie individuelleserverLa cohérence des données à l'extrémité dépend en fait d'un système appelézabAccord de base.zabLe nom complet du Protocole estzookeeper atomic broadcast zkProtocole de diffusion atomique,Peut être compris comme un protocole pour assurer la cohérence des transactions dans un environnement distribué.

InzkDans un environnement groupé,Est utilisé par une machine principale pour recevoir les instructions de demande du cluster(Appelé temporairementleader),Et à traversleaderCopie des instructions à chaquefollowerRôles pour la réplication des données.
Comment juger si la demande d'écriture a été soumise avec succès
QuandleaderLorsque les données sont écrites avec succès à plus de la moitié des noeuds, la demande d'écriture est soumise avec succès.Quels sont les détails du processus d'écriture de la demande??Les lecteurs, ne vous inquiétez pas.,Il y aura une explication détaillée ci - dessous..

Cohérence de l'engagement des transactions
Supposons qu'il y ait deux demandes d'écritureaEtb.
aDemande:Créer un /t1 Node of
bDemande:Créer un /t1/a Node of
À ce stade,,Il faut attendre.aLa transaction demandée a été entièrement engagée,ArrièrebDemande à exécuter.HypothèsesaLa demande n'a pas été soumise avec succès,À l'arrière.bLa demande ne sera pas exécutée avec succès.

zkCe qui se passe lors de l'écriture de données dans un environnement groupé

Le client se connecte d'abord àzkEnvironnement groupé,Les données à écrire sont ensuite soumises à l'un ou l'autrezkServeur,Si le serveur actuel estleader,ParleaderAccepté,Les données sont ensuite diffusées à chaque station du clusterfollowerMachines.Si la directive est acceptéefollower,La demande sera transmise àleader,Rediffusion à chaquefollowerMachines.

Les détails de la diffusion sont divisés en deux étapes:
Leader Accepter les nouvelles transactions du clientProposalDemande,Va faire un nouveauProposalDemande de diffusion à tous Follower.Comment confirmer une demande de diffusion,followerConfirmation de réception?A besoin d'unackRéponse à l'information sur les étiquettes pour la rétroaction.

Supposons que la moitié des machines du cluster soient retournéesackSignal,À ce stade,leaderIl est possible de retransmettre à chaque machinecommitC'est parti.,Et le comportement doit être enregistré localement dans le Journal des transactions après l'exécution.

Mode de récupération des pannes et mode de diffusion des messages
Mode crash
zkEn grappesleaderPeut - être à cause de la nervosité du réseau ou de quelque chose d'inhabituel,Perdu et le restefollowerLiens avec,Ce qui restefollowerNécessité de procéder à de nouvelles élections.
Ou si moins de la moitié des machines du cluster peuventleaderPour communiquer,Donc C'est le mode crash.,Nécessité de procéder à de nouvelles élections.

Mode de diffusion
ParleaderÀ chacunfollowerSignal de transmission de données synchrones,Envoyer divers messages de transaction et signaux de soumission.

zk Scénarios d'exception possibles pour les grappes

Photos: https://uploader.shimo.im/f/eBJlYx842UmUUcoo.png

zk Trop de noeuds dans , Le noeud racine ne peut pas être chargé .Colmatage

Photos: https://uploader.shimo.im/f/3xF98AE7xqkLOmnk.png
Qui a conduit à un grand nombrezkDemande d'interruption

zkPropriétés de notification des changements de données du noeud

Lorsque le client est lié àzkSur le serveur,Si les données d'un noeud changent,Tous les clients qui ont déjà écouté les données de ce noeud recevront le signal pertinent.

Qu'est - ce qui pourrait mal tourner??
Cette notification proactive est une faible cohérence finale,Et n'envoie qu'une seule notification,Ne garantit pas l'exactitude en temps réel des mises à jour.

Scénario d'application pratique

Il y a déjà beaucoup de choses sur InternetzkRéaliser des serrures distribuées,dubboCes cas dans le registre des services,Voici un exemple simple que j'ai écrit moi - même,Diffusez quelques idées de conception de vos lecteurs.

Gestion de l'environnement des grappes distribuées

UtilisézkLes noeuds ordonnés à l'intérieur pour réaliser la gestion des noeuds dans un environnement de Cluster distribué,La page de réflexion du design est relativement simple,Ajoutez un plug - in à chaque application au démarrage,Enregistrer en temps réel les attributs de performance pertinents pour le fonctionnement du programmezkDans un noeud spécifique de,Une fois le service terminé,Les données du noeud disparaîtront à temps.

UtilisationzkLa fonction de noeud séquentiel temporaire de:

Photos: https://uploader.shimo.im/f/4dUmAyEAhe5QnNUv.png

Organisation des idées:
Allez.zkUn noeud de(Supposons que:zk-agent Noeud)Créer un lot de noeuds ordonnés temporaires suivant:

zk-agent/server000001 //Hypothèses1Démarrage de la machine
zk-agent/server000002 //Hypothèses2Démarrage de la machine
zk-agent/server000003 //Hypothèses3Démarrage de la machine

Chaque noeud a des données d'écriture associées:

{
    "serverIp":"127.0.0.1","totalCpu":12,"totalMemory":17179869184,"totalMemoryDesc":"16GB","memoryUsage":"58.9%"}

Pour voir l'information, il suffit d'y accéderzkRegistre,Lisez les données sous le noeud.
Lorsque l'un des services est anormal,Des services connexes sont également nécessaireszkDéconnecter,Les données du noeud disparaissent.

Pourquoi pas?mysqlInformations sur le rendement du Service de stockage?
En fait, en utilisantmysql,redisUne base de données similaire est également possible,Mais il faut:
1.Les données peuvent être mises à jour de façon synchrone après la déconnexion du service
Et ça,En servicezookeeperC'est plus approprié.,Parce quezookeeperLes noeuds temporaires internes sont conçus pour supporter cette fonctionnalité.
Voici une liste de mes propres conceptions de codage,Pour votre information:
Dépendances connexes:

<dependencies>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.5.5</version>
    </dependency>
    <dependency>
        <groupId>com.101tec</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.11</version>
    </dependency>

    <dependency>
        <groupId>com.github.oshi</groupId>
        <artifactId>oshi-core</artifactId>
        <version>3.5.0</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.10.2</version>
    </dependency>

javaMise en œuvre du Code:


package org.idea.zookeeper.framework.agent;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.I0Itec.zkclient.ZkClient;

import java.lang.instrument.Instrumentation;

import static org.idea.zookeeper.framework.agent.OSOptCommonConstants.*;

/** * @author idea * @date created in 5:39 Après - midi 2020/11/9 */
public class ZkAgent {
    

    private static ZkClient zkClient;

    private static String nodePath;

    public static void premain(String args, Instrumentation instrumentation) {
    
        System.out.println("[ZkAgent] begin init ");
        if (args != null) {
    
            System.out.println(args);
        }
        zkClient = new ZkClient(ZK_SERVER);
        init();
    }

    /** * Initialisation de l'opération */
    public static void init() {
    
        if (!zkClient.exists(ROOT_PATH)) {
    
            zkClient.createPersistent(ROOT_PATH, "");
        }
        //Chemin du noeud actuellement créé
        nodePath = zkClient.createEphemeralSequential(SERVER_PATH, getOsBeanDesStr());
        System.out.println("Créer un noeud:" + nodePath);
        final Thread thread = new Thread(new Runnable() {
    
            @Override
            public void run() {
    
                while (true) {
    
                    //Le thread du démon calcule les informations de mémoire pertinentes
                    updateData(nodePath, getOsBeanDesStr());
                    try {
    
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
    
                        e.printStackTrace();
                    }
                }
            }
        });
        thread.setDaemon(true);
        thread.start();
    }

    /** * Obtenir la description du noeud * * @return */
    public static String getOsBeanDesStr() {
    
        //Obtenir des informations pertinentes au sein du système
        OSBean osBean = CPUMonitorUtil.getOSBean();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
    
            return objectMapper.writeValueAsString(osBean);
        } catch (JsonProcessingException e) {
    
            e.printStackTrace();
        }
        return null;
    }

    /** * Mettre à jour les informations de données du noeud * * @param path * @param data */
    public static void updateData(String path, Object data) {
    
        if (zkClient.exists(path)) {
    
            zkClient.writeData(path, data);
        } else {
    
            zkClient.createEphemeral(path, data);
        }
    }
}

En combinantjdkDeInstrumentationTechnique,Initialisation juste au moment du démarrage du programme pour obtenir des mesures de performance à l'intérieur du système d'exploitation.Créer un Thread de démon pour rafraîchir et signaler les paramètres de performance du système à un moment donné au noeud,Une fois le processus principal suspendu,Les fils du démon disparaissent.,Pour réaliser etzkDéconnecter la session,Les noeuds disparaissent.

VoirzkInformations sur les noeuds internes je n'ai conçu qu'une simple fenêtre de commande pour l'instant:

package org.idea.zookeeper.framework.agent;
/** * Obtenir certains services d'information sur les attributs au sein du système d'exploitation * * @author linhao * @date created in 8:51 Après - midi 2020/11/9 */
public interface OSInfoService {
    

    /** * SelonoptsPour voir différentes informations de données * */
    void doOptionInfo();
}

package org.idea.zookeeper.framework.agent;

import org.I0Itec.zkclient.ZkClient;

import java.util.List;
import java.util.Scanner;

import static org.idea.zookeeper.framework.agent.OSOptCommonConstants.*;

/** * @author linhao * @date created in 10:13 Après - midi 2020/11/9 */
public class OSInfoServiceImpl implements OSInfoService {
    

    private ZkClient zkClient;

    public OSInfoServiceImpl() {
    
        System.out.println("Initialisation de la connexionzk[" + ZK_SERVER + "]=====");
        this.zkClient = new ZkClient(ZK_SERVER);
    }

    @Override
    public void doOptionInfo() {
    
        while (true) {
    
            System.out.println("Veuillez exporter les instructions d'exécution:【】");
            Scanner scanner = new Scanner(System.in);
            int opts = scanner.nextInt();
            if (LIST_ALL == opts) {
    
                List<String> childrenList = zkClient.getChildren(ROOT_PATH);
                System.out.println(childrenList);
                for (String childPath : childrenList) {
    
                    Object nodeData = zkClient.readData(ROOT_PATH +"/"+ childPath);
                    System.out.println("【serverInfo】:" + nodeData);
                }
            } else if(EXIT == opts){
    
                return;
            }
        }
    }


    public static void main(String[] args) {
    
        OSInfoServiceImpl osInfoServiceOptioner = new OSInfoServiceImpl();
        osInfoServiceOptioner.doOptionInfo();
    }

}

Package plug - in asjarSac,Puis par injectionjavaagentDémarrage après commande:

-javaagent:/Users/idea/IdeaProjects/my-github/zookeeper-framework/zookeeper-agent/target/zk-agent.jar

Résultats pratiques
Démarrer les trois applications simultanément
Photos: https://uploader.shimo.im/f/Kue0F0AhM3A2TQJ6.png

Puis regardez le Centre de surveillance:
Photos: https://uploader.shimo.im/f/5CuacLNobzKC7Bbo.png

Ce n'est qu'une version grossière de la plateforme de gestion,Si vous êtes intéressé par cette idée, vous pouvez ajouter des données de surveillance plus détaillées,Par exemple:Convertit l'information de visualisation de la console en une bellewebInterface pour rendre,Ajouter la fonction d'écoute du noeud,Services de surveillance dynamique hors ligne et en ligne, etc..

Réponse aux questions

ps: Parce que cet article commence par javaUn ami Plate - forme du numéro public, Voici une question de l'un des lecteurs :

Salut, mon grand.,Deux questions:1 Y a - t - il seulement leaderResponsable de l'écriture(leaderLire+Écris.+Elections、follwerLire+Elections、observerLire); 2 leader Comparaison des élections ,Comparer d'abordzxid(Plus haut.32 Année de l'étiquette et faible 32 Numéro de transaction du BIT ), Comparer le numéro de la machine

Premier point
Voici ma pensée personnelle :
Première question:
leader Responsable de la lecture et de l'écriture .
follwer Responsable de la lecture, de l'écriture et de l'élection ( Lorsque le réseau est anormal ,Perdu.leader, L'état électoral est rétabli. ).Quandfollwer Quand j'ai reçu la commande Write , La commande est envoyée à leader,Parleader La directive est ensuite diffusée Proposal Pour chaque follwerNoeud. J'ai mentionné les détails de l'écriture des données des noeuds dans cet article. ,On peut voir.
observerEn fait, oui.zk Une conception d'optimisation des performances à un stade ultérieur de la grappe ,Similairefollwer Vous pouvez recevoir des instructions de lecture et d'écriture et les transmettre à leader, Mais il n'y participera pas. leaderDiffusionproposalAprès confirmationack Si plus de la moitié des votes .

Deuxième question:
La compréhension du lecteur est correcte ,
ZXIDEst une longueur64Nombre de bits,Faible32 Les bits sont incrémentés par des nombres , Toute modification des données entraînera ,Faible32 Nombre de bits plus simple 1.Élevé32- Oui.leaderNuméro du cycle,Chaque fois qu'un nouveauleaderHeure,Nouveauleader Je l'ai sorti du journal local. ZXID,Et puis il se résout haut32Numéro de cycle du BIT,Ajouter1,Plus bas32Tous les bits sont réglés à0. Cela garantit que chaque nouvelle élection leaderAprès,Promis.ZXID L'incrémentalité de .
myid Est unique pour chaque configuration autonome du serveur id,Seulement sizxid On ne les comparera pas tant qu'ils ne seront pas d'accord. myid.

版权声明
本文为[Danny... Idea]所创,转载请带上原文链接,感谢
https://cdmana.com/2022/01/202201080559031840.html

Scroll to Top