table des matières
Structure du canal
Processus d'exécution de Flume: Sources —— Processeur de canal —— Intercepteurs —— Sélecteur de canal —— Canaux —— Processeur récepteur —— Sinks
Parmi eux, il y a des transactions (put and take) de Soucrce à Channel et de Channel à Sink
Série Avro
Pour faire circuler les données entre plusieurs agents ou sauts, le récepteur de l'agent précédent et la source de l'agent actuel doivent être de type avro , et le puits pointe vers le nom d'hôte (ou l'adresse IP) et le port de la source. Ceci est la base d'autres structures complexes, mais il n'est pas recommandé de connecter trop de canaux, car trop de canaux affecteront non seulement le débit de transmission, mais une fois qu'un canal de nœud est en panne pendant le processus de transmission, cela affectera l'ensemble du système de transmission.
Copie et multiplex
Flume prend en charge le multiplexage des flux d'événements vers une ou plusieurs destinations. Ceci est réalisé en définissant un multiplexeur de flux qui peut répliquer ou acheminer sélectivement des événements vers un ou plusieurs canaux.
Dans l'exemple ci-dessus, vous pouvez voir que la source de l'agent nommé foo peut diviser le flux de données en trois canaux différents. Lors de la sélection d'un canal ( Channel Selector ), il peut s'agir de réplication (réplication) ou de multiplexage (multiplexage).
Pour la réplication, chaque événement est envoyé à tous les canaux. Pour le multiplexage, lorsque l'attribut de l'événement correspond à la valeur préconfigurée, l'événement est livré au canal disponible correspondant. Par exemple, dans l'exemple officiel suivant, si l'attribut de l'événement est défini sur CZ, le canal c1 est sélectionné; si l'attribut de l'événement est défini sur US, les canaux c2 et c3 sont sélectionnés; sinon, le canal c4 est sélectionné;
a1.sources = r1
a1.channels = c1 c2 c3 c4
a1.sources.r1.selector.type = multiplexage
a1.sources.r1.selector.header = état
a1.sources.r1.selector.mapping.CZ = c1
a1. sources.r1.selector.mapping.US = c2 c3
a1.sources.r1.selector.default = c4
Le sélecteur de canal sélectionne la stratégie de réplication par défaut (réplication)
Équilibrage de charge et basculement
Il existe trois types de processeur récepteur , à savoir DefaultSinkProcessor , LoadBalancingSinkProcessor et FailoverSinkProcessor .
DefaultSinkProcessor correspond à un seul Sink, LoadBalancingSinkProcessor et FailoverSinkProcessor correspondent au Sink Group, LoadBalancingSinkProcessor peut réaliser la fonction d'équilibrage de charge et FailoverSinkProcessor peut réaliser la fonction de basculement.
polymérisation
Ce mode est très courant et très pratique. Les applications Web quotidiennes sont généralement distribuées sur des milliers de serveurs, qui génèrent de nombreux journaux et sont très difficiles à traiter. L'utilisation de flume peut bien résoudre ce problème. Chaque serveur déploie un flume pour collecter les journaux et les transmet à un flume qui collecte les journaux, puis télécharge le flume vers hdfs, hive, hbase, etc. pour l'analyse des journaux.
Mécanisme de transaction
Mécanisme de transaction de Flume (similaire au mécanisme de transaction de base de données): Flume utilise deux transactions indépendantes pour être responsable de la livraison des événements de Soucrce au canal et du canal au récepteur . Par exemple, la source du répertoire de spoule crée un événement pour chaque ligne du fichier. Une fois que tous les événements de la transaction sont livrés au canal et que la soumission est réussie, Soucrce marquera le fichier comme terminé. De la même manière, la transaction gère le processus de transfert du canal au récepteur de la même manière. Si l'événement ne peut pas être enregistré pour une raison quelconque, la transaction sera annulée. Et tous les événements resteront dans la chaîne, en attendant d'être à nouveau livrés.
Selon les principes architecturaux de Flume, il est impossible pour Flume de perdre des données. Il dispose d'un mécanisme de transaction interne complet. La source vers le canal est transactionnelle et le canal vers le récepteur est transactionnel. Par conséquent, il n'y aura pas de perte de données dans ces deux liaisons. La seule situation de perte de données possible est que le canal utilise memoryChannel, que l'agent est arrêté et que les données sont perdues, ou que les données de stockage du canal sont pleines, ce qui fait que la source n'écrit plus et les données non écrites sont perdues.
Flume ne perdra pas de données, mais cela peut entraîner une duplication des données. Par exemple, si les données ont été envoyées avec succès par Sink mais qu'aucune réponse n'est reçue, Sink enverra à nouveau les données, ce qui peut entraîner une duplication des données.
Cas 1: source de données unique et exportations multiples
Analyse de cas
Utilisez Flume1 pour surveiller les modifications de fichier, Flume1 transmet les modifications à Flume2 et Flume2 est responsable de leur stockage dans HDFS . Dans le même temps, Flume1 transfère le contenu modifié vers Flume3 et Flume3 est responsable de la sortie vers le système de fichiers local .
Étapes du cas
-
Créez un fichier vide: touchez date.txt
-
Démarrez HDFS et Yarn: start-dfs.sh , start-yarn.sh
-
Créez trois fichiers de configuration, flume1.conf , flume2.conf , flume3.conf :
Le nom du premier agent est flume1 , une source est r1 , deux canaux sont c1 et c2 et deux puits sont k1 et k2. . Le type source est taildir , qui surveille le fichier local date.txt . Le type de puits est avro et les ports des deux puits sont différents et ils sont connectés aux deux autres agents. Le type de canal est la mémoire. Il existe trois types de
processeur récepteur , à savoir DefaultSinkProcessor , LoadBalancingSinkProcessor et FailoverSinkProcessor . Pour envoyer des données d'une source de données à différents endroits, un récepteur est lié à un canal et plusieurs canaux et récepteurs sont nécessaires.# Name the components on this agent a1.sources = r1 a1.channels = c1 c2 a1.sinks = k1 k2 将数据复制给所有channel# 将数据复制给所有channel(默认,可不写) a1.sources.r1.selector.type = replicating # Describe/configure the source a1.sources.r1.type = TAILDIR a1.sources.r1.filegroups = f1 a1.sources.r1.filegroups.f1 = /opt/flume-1.9.0/date.txt a1.sources.r1.positionFile = /opt/flume-1.9.0/file/position.json # Describe the sink a1.sinks.k1.type = avro a1.sinks.k1.hostname = master a1.sinks.k1.port = 44444 a1.sinks.k2.type = avro a1.sinks.k2.hostname = master a1.sinks.k2.port = 55555 # Use a channel which buffers events in memory a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 a1.channels.c2.type = memory a1.channels.c2.capacity = 1000 a1.channels.c2.transactionCapacity = 100 # Bind the source and sink to the channel a1.sources.r1.channels = c1 c2 a1.sinks.k1.channel = c1 a1.sinks.k2.channel = c2
Le type de source du deuxième agent est avro , qui est connecté au premier agent. Le type d'évier est HDFS .
# Name the components on this agent a2.sources = r1 a2.channels = c1 a2.sinks = k1 # Describe/configure the source a2.sources.r1.type = avro a2.sources.r1.bind = master a2.sources.r1.port = 44444 # Describe the sink a2.sinks.k1.type = hdfs a2.sinks.k1.hdfs.path = hdfs://master:9000/a/%Y%m%d/%H a2.sinks.k1.hdfs.filePrefix = logs a2.sinks.k1.hdfs.round = true a2.sinks.k1.hdfs.roundValue = 1 a2.sinks.k1.hdfs.roundUnit = hour a2.sinks.k1.hdfs.useLocalTimeStamp = true a2.sinks.k1.hdfs.batchSize = 100 a2.sinks.k1.hdfs.fileType = DataStream a2.sinks.k1.hdfs.rollInterval = 30 a2.sinks.k1.hdfs.rollSize = 134217700 a2.sinks.k1.hdfs.rollCount = 0 # Use a channel which buffers events in memory a2.channels.c1.type = memory a2.channels.c1.capacity = 1000 a2.channels.c1.transactionCapacity = 100 # Bind the source and sink to the channel a2.sources.r1.channels = c1 a2.sinks.k1.channel = c1
Le type de source du troisième agent est également avro , qui est connecté au premier agent. Le type de récepteur est file_roll .
# Name the components on this agent a3.sources = r1 a3.channels = c1 a3.sinks = k1 # Describe/configure the source a3.sources.r1.type = avro a3.sources.r1.bind = master a3.sources.r1.port = 55555 # Describe the sink a3.sinks.k1.type = file_roll a3.sinks.k1.sink.directory = /opt/flume-1.9.0/file # Use a channel which buffers events in memory a3.channels.c1.type = memory a3.channels.c1.capacity = 1000 a3.channels.c1.transactionCapacity = 100 # Bind the source and sink to the channel a3.sources.r1.channels = c1 a3.sinks.k1.channel = c1
-
Démarrez respectivement flume2, flume3, flume1. Notez 1 à la fin, car la source avro doit être le serveur.
bin/flume-ng agent -c conf -f flume2.conf -n a2 -Dflume.root.logger=INFO,console bin/flume-ng agent -c conf -f flume3.conf -n a3 -Dflume.root.logger=INFO,console bin/flume-ng agent -c conf -f flume1.conf -n a1 -Dflume.root.logger=INFO,console
-
Entrez date> date.txt pour modifier le fichier
Cas 2: basculement
Analyse de cas
Utilisation Flume1 surveiller un port qui évier groupe évier en butée respectivement Flume2 et Flume3 , en utilisant FailoverSinkProcessor , mettre en oeuvre un basculement de fonctionnalité.
Étapes du cas
-
Créez trois fichiers de configuration, flume1.conf , flume2.conf , flume3.conf : le
premier agent ajoute une configuration pour les groupes récepteurs , en utilisant la stratégie de basculement . Notez que, priorité k2 supérieure à k1 , donc k2 canal correspondant est activé , et k1 correspondant au canal est en veille# Name the components on this agent a1.sources = r1 a1.channels = c1 a1.sinks = k1 k2 a1.sinkgroups = g1 # Describe/configure the source a1.sources.r1.type = netcat a1.sources.r1.bind = master a1.sources.r1.bind = 33333 # Describe the sink a1.sinks.k1.type = avro a1.sinks.k1.hostname = master a1.sinks.k1.port = 44444 a1.sinks.k2.type = avro a1.sinks.k2.hostname = master a1.sinks.k2.port = 55555 # Sink groups a1.sinkgroups.g1.sinks = k1 k2 a1.sinkgroups.g1.processor.type = failover a1.sinkgroups.g1.processor.priority.k1 = 50 a1.sinkgroups.g1.processor.priority.k2 = 100 a1.sinkgroups.g1.processor.maxpenalty = 10000 # Use a channel which buffers events in memory a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 # Bind the source and sink to the channel a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1 a1.sinks.k2.channel = c1
Le type de puits du deuxième agent est un enregistreur
# Name the components on this agent a2.sources = r1 a2.channels = c1 a2.sinks = k1 # Describe/configure the source a2.sources.r1.type = avro a2.sources.r1.bind = master a2.sources.r1.port = 44444 # Describe the sink a2.sinks.k1.type = logger # Use a channel which buffers events in memory a2.channels.c1.type = memory a2.channels.c1.capacity = 1000 a2.channels.c1.transactionCapacity = 100 # Bind the source and sink to the channel a2.sources.r1.channels = c1 a2.sinks.k1.channel = c1
La configuration du deuxième et du troisième agent est similaire, mais le numéro de port est différent
# Name the components on this agent a3.sources = r1 a3.channels = c1 a3.sinks = k1 # Describe/configure the source a3.sources.r1.type = avro a3.sources.r1.bind = master a3.sources.r1.port = 55555 # Describe the sink a3.sinks.k1.type = logger # Use a channel which buffers events in memory a3.channels.c1.type = memory a3.channels.c1.capacity = 1000 a3.channels.c1.transactionCapacity = 100 # Bind the source and sink to the channel a3.sources.r1.channels = c1 a3.sinks.k1.channel = c1
-
Démarrez respectivement flume2, flume3, flume1.
bin/flume-ng agent -c conf -f flume2.conf -n a2 -Dflume.root.logger=INFO,console bin/flume-ng agent -c conf -f flume3.conf -n a3 -Dflume.root.logger=INFO,console bin/flume-ng agent -c conf -f flume1.conf -n a1 -Dflume.root.logger=INFO,console
-
Démarrez un nouveau terminal, tapez nc master 33333 , puis tapez quelque chose.
Le coin supérieur gauche est flume1 , le coin supérieur droit est flume2 , le coin inférieur gauche est flume3 et le coin inférieur droit est le client . Puisque la priorité du flume3 est supérieure à celle du flume2 , donc le flume3 est activé pour, le flume3 peut recevoir les informations.
A ce moment, flume3 raccroche, puis flume2 devient positif, de veille à activé , et peut recevoir des messages.
À ce moment, flume3 est ressuscité. La priorité de flume3 étant supérieure à flume2 , flume3 peut à nouveau recevoir des messages.
Cas 3: équilibrage de charge
Étapes du cas
-
Créez trois fichiers de configuration, flume1.conf , flume2.conf , flume3.conf . Parmi eux, flume2.conf et flume3.conf sont les mêmes que flume2 et flume3 dans le cas deux. flume1 est juste la stratégie de Sink Groups modifiée. Voici la configuration de flume1:
# Name the components on this agent a1.sources = r1 a1.channels = c1 a1.sinks = k1 k2 a1.sinkgroups = g1 # Describe/configure the source a1.sources.r1.type = netcat a1.sources.r1.bind = master a1.sources.r1.port = 33333 # Describe the sink a1.sinks.k1.type = avro a1.sinks.k1.hostname = master a1.sinks.k1.port = 44444 a1.sinks.k2.type = avro a1.sinks.k2.hostname = master a1.sinks.k2.port = 55555 # Sink groups a1.sinkgroups.g1.sinks = k1 k2 a1.sinkgroups.g1.processor.type = load_balance a1.sinkgroups.g1.processor.backoff = true a1.sinkgroups.g1.processor.selector = random # Use a channel which buffers events in memory a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 # Bind the source and sink to the channel a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1 a1.sinks.k2.channel = c1
-
Démarrez respectivement flume2, flume3, flume1. Démarrez un nouveau terminal, tapez nc master 33333, puis tapez quelque chose.
Le coin supérieur gauche est flume1 , le coin supérieur droit est flume2 , le coin inférieur gauche est flume3 et le coin inférieur droit est le client .
Cas 4: Agrégation
Analyse de cas
slave1 sur Flume1 surveillant un port de données, slave2 sur Flume2, le fichier local du moniteur date.txt , Flume1 et Flume2 envoient les données au maître sur Flume3 , Flume3 les données d'impression à la console.
Étapes du cas
-
Créez le fichier de configuration flume1.conf sur slave1. Le type de source est netcat , port d'écoute. : Le type d'évier est Avro , avec amarrage flume3.
# Name the components on this agent a1.sources = r1 a1.channels = c1 a1.sinks = k1 # Describe/configure the source a1.sources.r1.type = netcat a1.sources.r1.bind = localhost a1.sources.r1.port = 33333 # Describe the sink a1.sinks.k1.type = avro a1.sinks.k1.hostname = master a1.sinks.k1.port = 44444 # Use a channel which buffers events in memory a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 # Bind the source and sink to the channel a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1
Créez le fichier de configuration flume2.conf sur slave2. Le type de source est exec , qui surveille les fichiers. : Le type d'évier est Avro , avec amarrage flume3.
# Name the components on this agent a2.sources = r1 a2.channels = c1 a2.sinks = k1 # Describe/configure the source a2.sources.r1.type = exec a2.sources.r1.command = tail -F /opt/flume-1.9.0/date.txt # Describe the sink a2.sinks.k1.type = avro a2.sinks.k1.hostname = master a2.sinks.k1.port = 44444 # Use a channel which buffers events in memory a2.channels.c1.type = memory a2.channels.c1.capacity = 1000 a2.channels.c1.transactionCapacity = 100 # Bind the source and sink to the channel a2.sources.r1.channels = c1 a2.sinks.k1.channel = c1
Créez un fichier de configuration flume3.conf dans le master. source de type Avro , et flume2 flume1 recevant les données envoyées. : Le type de puits est logger , qui écrit les données reçues sur la console.
# Name the components on this agent a3.sources = r1 a3.channels = c1 a3.sinks = k1 # Describe/configure the source a3.sources.r1.type = avro a3.sources.r1.bind = master a3.sources.r1.port = 44444 # Describe the sink a3.sinks.k1.type = logger # Use a channel which buffers events in memory a3.channels.c1.type = memory a3.channels.c1.capacity = 1000 a3.channels.c1.transactionCapacity = 100 # Bind the source and sink to the channel a3.sources.r1.channels = c1 a3.sinks.k1.channel = c1
-
Démarrez respectivement flume2, flume3, flume1.
-
Entrez nc localhost 33333 dans slave1 , puis envoyez les données
-
Entrez date> date.txt dans slave2
-
Les données reçues peuvent être vues dans le maître