"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Propoño que lea a transcrición da conferencia "Hadoop. ZooKeeper" da serie "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Que é ZooKeeper, o seu lugar no ecosistema Hadoop. Falsedades sobre a computación distribuída. Diagrama dun sistema distribuído estándar. Dificultade para coordinar sistemas distribuídos. Problemas típicos de coordinación. Os principios detrás do deseño de ZooKeeper. Modelo de datos ZooKeeper. bandeiras znode. Sesións. API de cliente. Primitivas (configuración, pertenza a grupos, bloqueos simples, elección de líder, bloqueo sen efecto rabaño). Arquitectura ZooKeeper. ZooKeeper DB. ZAB. Xestor de solicitudes.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Hoxe falaremos de ZooKeeper. Esta cousa é moi útil. Como calquera produto Apache Hadoop, ten un logotipo. Representa un home.

Antes disto, falamos principalmente de como se poden procesar os datos alí, como almacenalos, é dicir, como usalos dalgún xeito e traballar con eles dalgún xeito. E hoxe gustaríame falar un pouco da construción de aplicacións distribuídas. E ZooKeeper é unha desas cousas que che permiten simplificar este asunto. Trátase dunha especie de servizo que se destina a algún tipo de coordinación da interacción de procesos en sistemas distribuídos, en aplicacións distribuídas.

A necesidade deste tipo de aplicacións é cada día máis grande, niso é o noso curso. Por unha banda, MapReduce e este marco prefabricado permite nivelar esta complexidade e liberar ao programador de escribir primitivos como a interacción e a coordinación de procesos. Pero, por outra banda, ninguén garante que non se teña que facer de todas formas. MapReduce ou outros cadros preparados non sempre substitúen completamente algúns casos que non se poden implementar usando isto. Incluíndo o propio MapReduce e unha morea de outros proxectos de Apache; de ​​feito, tamén son aplicacións distribuídas. E para facilitar a escritura, escribiron ZooKeeper.

Como todas as aplicacións relacionadas con Hadoop, foi desenvolvida por Yahoo! Agora tamén é unha aplicación oficial de Apache. Non está desenvolvido tan activamente como a HBase. Se vas a JIRA HBase, todos os días hai unha morea de informes de erros, unha morea de propostas para optimizar algo, é dicir, a vida no proxecto está a suceder constantemente. E ZooKeeper, por unha banda, é un produto relativamente sinxelo e, por outra banda, iso garante a súa fiabilidade. E é bastante sinxelo de usar, polo que se converteu nun estándar en aplicacións dentro do ecosistema Hadoop. Así que pensei que sería útil revisalo para entender como funciona e como utilizalo.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Esta é unha imaxe dunha charla que tivemos. Podemos dicir que é ortogonal a todo o que consideramos ata agora. E todo o que aquí se indica, nun ou outro grao, funciona con ZooKeeper, é dicir, é un servizo que utiliza todos estes produtos. Nin HDFS nin MapReduce escriben os seus propios servizos similares que funcionen especificamente para eles. En consecuencia, úsase ZooKeeper. E isto simplifica o desenvolvemento e algunhas cousas relacionadas con erros.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

De onde vén todo isto? Parece que lanzamos dúas aplicacións en paralelo en ordenadores diferentes, conectamos cunha cadea ou nunha malla, e todo funciona. Pero o problema é que a Rede non é fiable, e se cheiraches o tráfico ou miraches o que está a suceder alí a un nivel baixo, como interactúan os clientes na Rede, moitas veces podes ver que algúns paquetes se perden ou se reenvían. Non por nada se inventaron os protocolos TCP, que permiten establecer unha sesión determinada e garantir a entrega de mensaxes. Pero en calquera caso, nin sequera TCP pode salvarte. Todo ten un tempo morto. A rede pode simplemente caer por un tempo. Pode que só parpadee. E todo isto leva ao feito de que non pode confiar en que a Rede sexa fiable. Esta é a principal diferenza de escribir aplicacións paralelas que se executan nun ordenador ou nun superordenador, onde non hai Rede, onde hai un bus de intercambio de datos máis fiable na memoria. E esta é unha diferenza fundamental.

Entre outras cousas, ao utilizar a Rede, sempre hai unha certa latencia. O disco tamén o ten, pero a Rede ten máis. A latencia é un tempo de atraso, que pode ser pequeno ou bastante significativo.

A topoloxía da rede está cambiando. Que é a topoloxía: esta é a colocación do noso equipo de rede. Hai centros de datos, hai racks que están alí, hai velas. Todo isto pódese volver conectar, mover, etc. Tamén hai que telo en conta. Os nomes IP cambian, cambia o enrutamento polo que viaxa o noso tráfico. Isto tamén hai que telo en conta.

A rede tamén pode cambiar en termos de equipamento. Pola práctica, podo dicir que aos nosos enxeñeiros de rede lles gusta moito actualizar periodicamente algo sobre as velas. De súpeto saíu un novo firmware e non estaban especialmente interesados ​​nalgún clúster de Hadoop. Teñen o seu propio traballo. Para eles, o principal é que a Rede funcione. En consecuencia, queren volver cargar algo alí, facer un parpadeo no seu hardware e o hardware tamén cambia periodicamente. Todo isto dalgún xeito hai que telo en conta. Todo isto afecta á nosa aplicación distribuída.

Normalmente as persoas que comezan a traballar con grandes cantidades de datos por algún motivo cren que Internet é ilimitada. Se hai un ficheiro de varios terabytes alí, pode levalo ao seu servidor ou ordenador e abrilo usando gato e mira. Outro erro está en vitalidade mira os rexistros. Nunca fagas isto porque é malo. Porque Vim tenta almacenar todo, cargar todo na memoria, especialmente cando comezamos a movernos por este rexistro e buscamos algo. Son cousas que se esquecen, pero que paga a pena ter en conta.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

É máis doado escribir un programa que se execute nun ordenador cun procesador.

Cando o noso sistema crece, queremos paralelizalo todo, e paralelizalo non só nun ordenador, senón tamén nun clúster. Xorde a pregunta: como coordinar este asunto? As nosas aplicacións poden nin sequera interactuar entre si, pero executamos varios procesos en paralelo en varios servidores. E como controlar que todo lles vai ben? Por exemplo, envían algo por Internet. Deben escribir sobre o seu estado nalgún lugar, por exemplo, nalgún tipo de base de datos ou rexistro, despois agregar este rexistro e analizalo nalgún lugar. Ademais, hai que ter en conta que o proceso estaba funcionando e funcionando, de súpeto apareceu algún erro ou fallou, entón con que rapidez nos enteramos?

Está claro que todo isto pódese controlar rapidamente. Isto tamén é bo, pero o seguimento é algo limitado que che permite supervisar algunhas cousas ao máis alto nivel.

Cando queremos que os nosos procesos comecen a interactuar entre si, por exemplo, para enviarse algúns datos, entón xorde tamén a pregunta: como vai ocorrer isto? Haberá algún tipo de condición de carreira, sobrescribiranse entre si, chegarán os datos correctamente, perderase algo no camiño? Necesitamos desenvolver algún tipo de protocolo, etc.

A coordinación de todos estes procesos non é cousa trivial. E obriga ao desenvolvedor a baixar a un nivel aínda máis baixo e escribir sistemas desde cero ou non desde cero, pero isto non é tan sinxelo.

Se creas un algoritmo criptográfico ou incluso o implementas, bótao inmediatamente, porque o máis probable é que non che funcione. O máis probable é que conteña unha morea de erros que esqueceches de proporcionar. Nunca o use para nada serio porque o máis probable é que sexa inestable. Porque todos os algoritmos que existen foron probados polo tempo durante moito tempo. Está molestado pola comunidade. Este é un tema separado. E aquí pasa o mesmo. Se é posible non implementar algún tipo de sincronización de procesos por si mesmo, entón é mellor non facelo, porque é bastante complicado e lévache polo inestable camiño da busca constante de erros.

Hoxe falamos de ZooKeeper. Por unha banda, é un marco, por outra, é un servizo que facilita a vida ao desenvolvedor e simplifica ao máximo a implantación da lóxica e a coordinación dos nosos procesos.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Lembremos como pode ser un sistema distribuído estándar. Isto é do que falamos: HDFS, HBase. Hai un proceso Mestre que xestiona os procesos de traballadores e escravos. É o encargado de coordinar e distribuír as tarefas, reiniciar os traballadores, lanzar outros novos e distribuír a carga.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Unha cousa máis avanzada é o Servizo de Coordinación, é dicir, mover a propia tarefa de coordinación a un proceso separado, ademais de executar algún tipo de backup ou Master en espera en paralelo, porque o Master pode fallar. E se o Mestre cae, entón o noso sistema non funcionará. Estamos executando copias de seguridade. Algúns estados indican que o mestre ten que ser replicado na copia de seguridade. Tamén se pode encomendar ao Servizo de Coordinación. Pero neste diagrama, o propio Mestre é o responsable da coordinación dos traballadores; aquí o servizo está a coordinar as actividades de replicación de datos.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Unha opción máis avanzada é cando toda a coordinación corre a cargo do noso servizo, como adoita facer. Asume a responsabilidade de asegurarse de que todo funcione. E se algo non funciona, decatámonos e intentamos sortear esta situación. En todo caso, quédanos un Mestre que dalgún xeito interactúa con escravos e pode enviar datos, información, mensaxes, etc a través dalgún servizo.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Hai un esquema aínda máis avanzado, cando non temos un Mestre, todos os nodos son escravos mestres, diferentes no seu comportamento. Pero aínda teñen que interactuar entre eles, polo que aínda queda algún servizo para coordinar estas accións. Probablemente, Cassandra, que traballa con este principio, encaixa neste esquema.

É difícil dicir cal destes esquemas funciona mellor. Cada un ten os seus pros e contras.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

E non hai que ter medo a algunhas cousas co Mestre, porque, como mostra a práctica, non é tan susceptible de servir constantemente. O principal aquí é escoller a solución adecuada para hospedar este servizo nun nodo poderoso separado, para que teña recursos suficientes, para que, se é posible, os usuarios non teñan acceso alí, para que non mateen accidentalmente este proceso. Pero ao mesmo tempo, nun esquema deste tipo é moito máis sinxelo xestionar os traballadores desde o proceso Master, é dicir, este esquema é máis sinxelo desde o punto de vista da implementación.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

E este esquema (arriba) probablemente sexa máis complexo, pero máis fiable.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

O principal problema son os fallos parciais. Por exemplo, cando enviamos unha mensaxe pola Rede, prodúcese algún tipo de accidente e o que enviou a mensaxe non saberá se a súa mensaxe foi recibida e o que pasou por parte do receptor, non saberá se a mensaxe foi procesada correctamente. , é dicir, non recibirá ningunha confirmación.

En consecuencia, debemos procesar esta situación. E o máis sinxelo é reenviar esta mensaxe e esperar ata que recibamos unha resposta. Neste caso, non se ten en conta se o estado do receptor cambiou. Podemos enviar unha mensaxe e engadir os mesmos datos dúas veces.

ZooKeeper ofrece formas de xestionar estes rexeitamentos, o que tamén facilita as nosas vidas.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Como se mencionou un pouco antes, isto é semellante a escribir programas multifíos, pero a principal diferenza é que nas aplicacións distribuídas que construímos en máquinas diferentes, a única forma de comunicarnos é a Rede. Esencialmente, esta é unha arquitectura de nada compartido. Cada proceso ou servizo que se executa nunha máquina ten a súa propia memoria, o seu propio disco, o seu propio procesador, que non comparte con ninguén.

Se escribimos un programa multiproceso nun ordenador, podemos usar a memoria compartida para intercambiar datos. Temos un cambio de contexto alí, os procesos poden cambiar. Isto afecta o rendemento. Por unha banda, non hai tal cousa no programa nun clúster, pero hai problemas coa Rede.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

En consecuencia, os principais problemas que xorden ao escribir sistemas distribuídos son a configuración. Estamos escribindo algún tipo de aplicación. Se é sinxelo, codificamos todo tipo de números no código, pero isto é un inconveniente, porque se decidimos que en lugar dun tempo de espera de medio segundo queremos un tempo de espera dun segundo, entón necesitamos recompilar a aplicación e tira todo de novo. Unha cousa é cando está nunha máquina, cando podes reiniciala, pero cando temos moitas máquinas, temos que copiar todo constantemente. Debemos tentar que a aplicación sexa configurable.

Aquí estamos a falar da configuración estática para os procesos do sistema. Isto non é totalmente, quizais desde o punto de vista do sistema operativo, pode ser unha configuración estática para os nosos procesos, é dicir, esta é unha configuración que simplemente non se pode tomar e actualizar.

Tamén hai unha configuración dinámica. Estes son os parámetros que queremos cambiar sobre a marcha para que sexan recollidos alí.

Cal é o problema aquí? Actualizamos a configuración, lanzámola, entón que? O problema pode ser que, por unha banda, lanzamos a configuración, pero esquecémonos do novo, a configuración quedou alí. En segundo lugar, mentres estabamos a lanzar, a configuración actualizouse nalgúns lugares, pero noutros non. E algúns procesos da nosa aplicación que se executan nunha máquina reiniciáronse cunha configuración nova e nalgún lugar cunha antiga. Isto pode provocar que a nosa aplicación distribuída sexa incoherente desde a perspectiva da configuración. Este problema é común. Para unha configuración dinámica, é máis relevante porque implica que se pode cambiar sobre a marcha.

Outro problema é a pertenza ao grupo. Sempre temos algún conxunto de traballadores, sempre queremos saber cal deles está vivo, cal deles está morto. Se hai un Mestre, entón debe entender que traballadores poden ser redirixidos aos clientes para que realicen cálculos ou traballen con datos e cales non. Un problema que xorde constantemente é que necesitamos saber quen está a traballar no noso clúster.

Outro problema típico son as eleccións de líderes, cando queremos saber quen manda. Un exemplo é a replicación, cando temos algún proceso que recibe operacións de escritura e despois as replica entre outros procesos. El será o líder, todos o obedecerán, seguirano. É necesario elixir un proceso para que sexa inequívoco para todos, para que non resulte que se seleccionen dous líderes.

Tamén hai acceso mutuamente excluínte. O problema aquí é máis complexo. Hai algo como un mutex, cando escribes programas multi-fíos e queres que o acceso a algún recurso, por exemplo, unha cela de memoria, estea limitado e realizado por un só fío. Aquí o recurso podería ser algo máis abstracto. E as diferentes aplicacións dos distintos nodos da nosa Rede só deberían recibir acceso exclusivo a un determinado recurso, e non para que todos poidan cambialo ou escribir algo alí. Estes son os chamados peches.

ZooKeeper permítelle resolver todos estes problemas nun ou outro grao. E mostrarei con exemplos como che permite facelo.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Non hai primitivos de bloqueo. Cando comezamos a usar algo, este primitivo non esperará a que se produza ningún evento. O máis probable é que isto funcione de forma asíncrona, permitindo así que os procesos non se colguen mentres esperan algo. Esta é unha cousa moi útil.

Todas as solicitudes dos clientes son procesadas na orde da cola xeral.

E os clientes teñen a oportunidade de recibir notificacións sobre cambios nalgún estado, sobre cambios nos datos, antes de que o cliente vexa os datos modificados.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

ZooKeeper pode funcionar en dous modos. O primeiro é autónomo, nun nodo. Isto é conveniente para probar. Tamén pode funcionar en modo clúster en calquera número de servidores. Se temos un clúster de 100 máquinas, entón non é necesario que funcione en 100 máquinas. É suficiente con seleccionar varias máquinas onde podes executar ZooKeeper. E profesa o principio de alta dispoñibilidade. En cada instancia en execución, ZooKeeper almacena unha copia completa dos datos. Máis tarde xa vos contarei como o fai. Non divide datos nin os particiona. Por unha banda, é un inconveniente que non podemos almacenar moito, por outra banda, non hai que facelo. Non é para iso, non é unha base de datos.

Os datos pódense almacenar no lado do cliente. Este é un principio estándar para que non interrompamos o servizo e non o carguemos coas mesmas solicitudes. Un cliente intelixente adoita saber sobre isto e almacenalo na caché.

Por exemplo, algo cambiou aquí. Hai algún tipo de aplicación. Elixiuse un novo líder, que é o responsable, por exemplo, do procesamento das operacións de escritura. E queremos replicar os datos. Unha solución é poñelo nun bucle. E cuestionamos constantemente o noso servizo: cambiou algo? A segunda opción é máis óptima. Este é un mecanismo de vixilancia que che permite notificar aos clientes que algo cambiou. Este é un método menos custoso en termos de recursos e máis cómodo para os clientes.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

O cliente é o usuario que usa ZooKeeper.

O servidor é o propio proceso de ZooKeeper.

Znode é a clave en ZooKeeper. Todos os znodes son almacenados na memoria por ZooKeeper e están organizados en forma de diagrama xerárquico, en forma de árbore.

Hai dous tipos de operacións. O primeiro é actualizar/escritura, cando algunha operación cambia o estado da nosa árbore. A árbore é común.

E é posible que o cliente non complete unha solicitude e se desconecte, pero poida establecer unha sesión a través da cal interactúa con ZooKeeper.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

O modelo de datos de ZooKeeper semella un sistema de ficheiros. Hai unha raíz estándar e despois fomos como polos directorios que van dende a raíz. E despois o catálogo do primeiro nivel, segundo nivel. Todo isto é znodes.

Cada znode pode almacenar algúns datos, normalmente non moi grandes, por exemplo, 10 kilobytes. E cada znode pode ter un determinado número de fillos.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Os Znodes veñen en varios tipos. Pódense crear. E ao crear un znode, especificamos o tipo ao que debe pertencer.

Hai dous tipos. A primeira é a bandeira efémera. Znode vive dentro dunha sesión. Por exemplo, o cliente estableceu unha sesión. E mentres esta sesión estea viva, existirá. Isto é necesario para non producir algo innecesario. Isto tamén é adecuado para momentos nos que é importante almacenar datos primitivos nunha sesión.

O segundo tipo é a bandeira secuencial. Incrementa o contador no camiño cara ao znode. Por exemplo, tiñamos un directorio coa aplicación 1_5. E cando creamos o primeiro nodo, recibiu p_1, o segundo - p_2. E cando chamamos a este método cada vez, pasamos o camiño completo, indicando só unha parte do camiño, e este número increméntase automaticamente porque indicamos o tipo de nodo - secuencial.

Znode regular. Sempre vivirá e terá o nome que lle digamos.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Outra cousa útil é a bandeira do reloxo. Se o instalamos, entón o cliente pode subscribirse a algúns eventos para un nodo específico. Vouche amosar máis tarde cun exemplo de como se fai isto. O propio ZooKeeper notifica ao cliente que os datos do nodo cambiaron. Non obstante, as notificacións non garanten a chegada de datos novos. Simplemente din que algo cambiou, polo que aínda tes que comparar os datos máis tarde con chamadas separadas.

E como xa dixen, a orde dos datos está determinada por kilobytes. Non é necesario almacenar datos de texto grande alí, porque non é unha base de datos, é un servidor de coordinación de accións.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Vouvos falar un pouco das sesións. Se temos varios servidores, podemos movernos de forma transparente dun servidor a outro usando o identificador de sesión. É bastante cómodo.

Cada sesión ten algún tipo de tempo morto. Unha sesión defínese por se o cliente envía algo ao servidor durante esa sesión. Se non transmitiu nada durante o tempo de espera, a sesión cae ou o cliente pode pechala el mesmo.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Non ten tantas funcións, pero podes facer cousas diferentes con esta API. Esa chamada que vimos de crear crea un znode e toma tres parámetros. Este é o camiño ao znode, e debe especificarse por completo desde a raíz. E tamén estes son algúns datos que queremos transferir alí. E o tipo de bandeira. E despois da creación devolve o camiño ao znode.

En segundo lugar, podes eliminalo. O truco aquí é que o segundo parámetro, ademais do camiño ao znode, pode especificar a versión. En consecuencia, ese znode eliminarase se a súa versión que transferimos é equivalente á que existe realmente.

Se non queremos comprobar esta versión, simplemente pasamos o argumento "-1".

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

En terceiro lugar, comproba a existencia dun znode. Devolve verdadeiro se o nodo existe, false en caso contrario.

E entón aparece o reloxo de marca, que che permite supervisar este nodo.

Podes establecer esta marca incluso nun nodo inexistente e recibir unha notificación cando apareza. Isto tamén pode ser útil.

Hai un par de retos máis getData. Está claro que podemos recibir datos a través de znode. Tamén podes usar o reloxo de bandeiras. Neste caso, non se instalará se non hai un nodo. Polo tanto, cómpre entender que existe e despois recibir datos.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Tamén hai SetData. Aquí pasamos a versión. E se transmitimos isto, actualizaranse os datos do znode dunha determinada versión.

Tamén pode especificar "-1" para excluír esta comprobación.

Outro método útil é getChildren. Tamén podemos obter unha lista de todos os znodes que lle pertencen. Podemos controlar isto configurando a vixilancia da bandeira.

E método sincronizar permite que todos os cambios se envíen á vez, garantindo así que se gardan e que todos os datos se modifiquen completamente.

Se trazamos analoxías coa programación convencional, cando usas métodos como escribir, que escriben algo no disco, e despois de que che devolva unha resposta, non hai garantía de que escribiches os datos no disco. E mesmo cando o sistema operativo está seguro de que todo está escrito, hai mecanismos no propio disco onde o proceso pasa por capas de búfers, e só despois diso os datos colócanse no disco.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

A maioría utilízanse chamadas asíncronas. Isto permite que o cliente traballe en paralelo con diferentes solicitudes. Podes usar o enfoque sincrónico, pero é menos produtivo.

As dúas operacións das que falamos son actualizar/escritura, que cambian datos. Estes son crear, configurar datos, sincronizar e eliminar. E read is existe, getData, getChildren.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Agora algúns exemplos de como podes facer primitivos para traballar nun sistema distribuído. Por exemplo, relacionado coa configuración de algo. Apareceu un novo traballador. Engadimos a máquina e iniciamos o proceso. E hai as seguintes tres preguntas. Como consulta a ZooKeeper para a configuración? E se queremos cambiar a configuración, como a cambiamos? E despois de que o cambiamos, como o conseguen os traballadores que tiñamos?

ZooKeeper fai isto relativamente fácil. Por exemplo, está a nosa árbore znode. Aquí hai un nodo para a nosa aplicación, creamos un nodo adicional nel, que contén datos da configuración. Estes poden ser ou non parámetros separados. Dado que o tamaño é pequeno, o tamaño da configuración adoita ser tamén pequeno, polo que é moi posible gardalo aquí.

Estás usando o método getData para obter a configuración para o traballador desde o nodo. Establecido como verdadeiro. Se por algún motivo este nodo non existe, seremos informados sobre el cando apareza, ou cando cambie. Se queremos saber que algo cambiou, poñémolo como verdadeiro. E se os datos deste nodo cambian, saberémolo.

SetData. Establecemos os datos, establecemos "-1", é dicir, non comprobamos a versión, asumimos que sempre temos unha configuración, non necesitamos almacenar moitas configuracións. Se necesitas almacenar moito, terás que engadir outro nivel. Aquí cremos que só hai un, polo que actualizamos só a máis recente, polo que non comprobamos a versión. Neste momento, todos os clientes que se subscribían previamente reciben unha notificación de que algo cambiou neste nodo. E despois de recibilo, tamén deberán solicitar de novo os datos. A notificación é que non reciben os datos en si, senón só a notificación dos cambios. Despois disto deberán solicitar novos datos.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

A segunda opción para usar o primitivo é pertenza a un grupo. Temos unha aplicación distribuída, hai unha morea de traballadores e queremos entender que están todos no seu sitio. Polo tanto, deben rexistrarse eles mesmos que traballan na nosa aplicación. E tamén queremos coñecer, ben dende o proceso Máster ou noutro sitio, todos os traballadores en activo cos que contamos na actualidade.

Como facemos isto? Para a aplicación, creamos un nodo de traballadores e engadimos alí un subnivel usando o método create. Teño un erro na diapositiva. Aquí necesitas secuencial especifique, entón todos os traballadores serán creados un por un. E a aplicación, solicitando todos os datos sobre os fillos deste nodo, recibe todos os traballadores activos que existen.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Esta é unha implementación tan terrible de como se pode facer isto en código Java. Comecemos polo final, co método principal. Esta é a nosa clase, imos crear o seu método. Como primeiro argumento usamos host, onde nos estamos conectando, é dicir, establecémolo como argumento. E o segundo argumento é o nome do grupo.

Como ocorre a conexión? Este é un exemplo sinxelo da API que se usa. Todo é relativamente sinxelo aquí. Hai un ZooKeeper de clase estándar. Pasámoslle hostias. E establece o tempo de espera, por exemplo, en 5 segundos. E temos un membro chamado ConnectedSignal. Esencialmente, creamos un grupo ao longo do camiño transmitido. Non escribimos datos alí, aínda que se puido escribir algo. E o nodo aquí é do tipo persistente. Esencialmente, este é un nodo regular común que existirá todo o tempo. Aquí é onde se crea a sesión. Esta é a implementación do propio cliente. O noso cliente enviará mensaxes periódicas indicando que a sesión está activa. E cando rematamos a sesión, chamamos a pechar e xa está, a sesión cae. Isto é por se nos cae algo, para que ZooKeeper se entera e corte a sesión.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Como bloquear un recurso? Aquí todo é un pouco máis complicado. Temos un conxunto de traballadores, hai algún recurso que queremos bloquear. Para iso, creamos un nodo separado, por exemplo, chamado lock1. Se fomos capaces de crealo, entón temos un bloqueo aquí. E se non puidemos crealo, entón o traballador tenta obter getData desde aquí e, dado que o nodo xa foi creado, poñemos aquí un observador e no momento en que cambie o estado deste nodo, sabémolo. E podemos tentar ter tempo para recrealo. Se tomamos este nodo, tomamos este bloqueo, despois de que xa non necesitemos o bloqueo, abandonarémolo, xa que o nodo só existe dentro da sesión. En consecuencia, desaparecerá. E outro cliente, no marco doutra sesión, poderá pechar o bloqueo neste nodo, ou mellor dito, recibirá unha notificación de que algo cambiou e poderá tentar facelo a tempo.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Outro exemplo de como podes escoller o líder principal. Isto é un pouco máis complicado, pero tamén relativamente sinxelo. Que está pasando aquí? Hai un nodo principal que agrega a todos os traballadores. Estamos tentando obter datos sobre o líder. Se isto ocorreu con éxito, é dicir, recibimos algúns datos, entón o noso traballador comeza a seguir a este líder. Cre que xa hai un líder.

Se o líder morreu por algún motivo, por exemplo, caeu, entón intentamos crear un novo líder. E se o logramos, entón o noso traballador convértese no líder. E se alguén neste momento conseguiu crear un novo líder, entón intentamos entender quen é e despois seguilo.

Aquí xorde o denominado efecto rabaño, é dicir, o efecto rabaño, porque cando un líder morre, o que sexa o primeiro en tempo converterase en líder.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Ao capturar un recurso, pode tentar utilizar un enfoque lixeiramente diferente, que é o seguinte. Por exemplo, queremos conseguir un bloqueo, pero sen o efecto hert. Consistirá no feito de que a nosa aplicación solicita listas de todos os ID de nodos para un nodo xa existente cun bloqueo. E se antes o nodo para o que creamos un bloqueo é o máis pequeno do conxunto que recibimos, isto significa que capturamos o bloqueo. Comprobamos que recibimos un bloqueo. Como comprobación, haberá unha condición de que o ID que recibimos ao crear un novo bloqueo sexa mínimo. E se o recibimos, traballaremos máis.

Se hai un identificador determinado que é menor que o noso bloqueo, poñemos un observador neste evento e esperamos a notificación ata que algo cambie. É dicir, recibimos este bloqueo. E ata que se desprenda, non nos converteremos na identificación mínima e non recibiremos o bloqueo mínimo, e así poderemos iniciar sesión. E se non se cumpre esta condición, imos inmediatamente aquí e tentamos volver conseguir este bloqueo, porque algo puido cambiar durante este tempo.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

En que consiste ZooKeeper? Hai 4 cousas principais. Trátase de procesos de procesamento - Solicitude. E tamén ZooKeeper Atomic Broadcast. Hai un rexistro de commit onde se rexistran todas as operacións. E a propia base de datos replicada en memoria, é dicir, a propia base de datos onde se almacena toda esta árbore.

Paga a pena notar que todas as operacións de escritura pasan polo Procesador de solicitudes. E as operacións de lectura van directamente á base de datos en memoria.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

A propia base de datos está totalmente replicada. Todas as instancias de ZooKeeper almacenan unha copia completa dos datos.

Para restaurar a base de datos despois dun fallo, hai un rexistro de confirmación. A práctica estándar é que antes de que os datos entren na memoria, escríbanse alí para que, se falla, este rexistro poida reproducirse e restaurar o estado do sistema. E tamén se utilizan instantáneas periódicas da base de datos.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

ZooKeeper Atomic Broadcast é unha cousa que se usa para manter datos replicados.

ZAB selecciona internamente un líder desde o punto de vista do nodo ZooKeeper. Outros nodos convértense nos seus seguidores e esperan algunhas accións dela. Se reciben entradas, remítenas todas ao líder. Primeiro realiza unha operación de escritura e despois envía unha mensaxe sobre o que cambiou aos seus seguidores. Isto, de feito, debe realizarse atomicamente, é dicir, a operación de gravación e emisión de todo debe realizarse atomicamente, garantindo así a coherencia dos datos.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop" Só procesa solicitudes de escritura. A súa tarefa principal é transformar a operación nunha actualización transaccional. Esta é unha solicitude xerada especialmente.

E aquí cabe destacar que está garantida a idempotencia das actualizacións para a mesma operación. Que é? Esta cousa, se se executa dúas veces, terá o mesmo estado, é dicir, a propia solicitude non cambiará. E hai que facer isto para que, en caso de fallo, poida reiniciar a operación, retrotraendo así os cambios que se produciron no momento. Neste caso, o estado do sistema pasará a ser o mesmo, é dicir, non debería darse o caso de que unha serie do mesmo, por exemplo, procesos de actualización, conducise a diferentes estados finais do sistema.

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

"Hadoop. ZooKeeper" da serie Mail.Ru Group Technostream "Métodos para o procesamento distribuído de grandes volumes de datos en Hadoop"

Fonte: www.habr.com

Engadir un comentario