¿Modelado de datos con Kafka? Temas y particiones

178

Una de las primeras cosas en las que pienso cuando utilizo un nuevo servicio (como un almacén de datos que no es RDBMS o una cola de mensajes) es: "¿Cómo debo estructurar mis datos?".

He leído y visto algunos materiales introductorios. En particular, tomemos, por ejemplo, Kafka: un sistema de mensajería distribuida para el procesamiento de registros , que escribe:

  • "un tema es el contenedor con el que se asocian los mensajes"
  • "la unidad más pequeña de paralelismo es la partición de un tema. Esto implica que todos los mensajes que ... pertenecen a una partición particular de un tema serán consumidos por un consumidor en un grupo de consumidores".

Sabiendo esto, ¿cuál sería un buen ejemplo que ilustre cómo usar temas y particiones? ¿Cuándo debería algo ser un tema? ¿Cuándo debería ser algo una partición?

Como ejemplo, digamos que mis datos (Clojure) se ven así:

{:user-id 101 :viewed "/page1.html" :at #inst "2013-04-12T23:20:50.22Z"}
{:user-id 102 :viewed "/page2.html" :at #inst "2013-04-12T23:20:55.50Z"}

¿Debería basarse el tema en user-id? viewed? at? ¿Qué pasa con la partición?

¿Cómo decido?

2
  • 3
    Es extraño, esto habla de temas y particiones, pero no necesariamente de la evolución de los datos dentro de ellos. ¿Qué pasa si desea adjuntar agentes de usuario o encabezados a esos eventos de "vista de usuario"? ¿Cómo evolucionas y comunicas eso de una manera a los consumidores intermedios? 11/09/18 a las 6:26
  • @OneCricketeer Suena como una pregunta separada para mí :) Adelante ... 4 de diciembre de 2020 a las 1:47
143

Al estructurar sus datos para Kafka, realmente depende de cómo se vayan a consumir.

En mi opinión, un tema es una agrupación de mensajes de un tipo similar que serán consumidos por el mismo tipo de consumidor, por lo que en el ejemplo anterior, solo tendría un solo tema y si decides impulsar algún otro tipo de datos a través de Kafka, puede agregar un nuevo tema para eso más adelante.

Los temas se registran en ZooKeeper, lo que significa que puede tener problemas si intenta agregar demasiados, por ejemplo, el caso en el que tiene un millón de usuarios y ha decidido crear un tema por usuario.

Las particiones, por otro lado, son una forma de paralelizar el consumo de los mensajes. El número total de particiones en un clúster de agentes debe ser al menos el mismo que el número de consumidores en un grupo de consumidores para entender la función de partición. Los consumidores de un grupo de consumidores dividirán la carga de procesar el tema entre ellos de acuerdo con la partición, de modo que un consumidor solo se ocupará de los mensajes de la partición a la que está "asignada".

El particionamiento se puede configurar explícitamente usando una clave de partición en el lado del productor o, si no se proporciona, se seleccionará una partición aleatoria para cada mensaje.

4
  • 5
    Entonces, en lugar de usar los temas como la forma de obtener datos por identificación de usuario, abrumando así a Zookeeper, es mejor particionar por identificación de usuario y que los consumidores basados ​​en la identificación de usuario se suscriban a cada partición si? 19 de septiembre de 2013 a las 19:41
  • 2
  • 5
    @RavindranathAkila Kafka is designed to have of the order of few thousands of partitions roughly less than 10,000. And the main bottleneck is zookeeper. A better way to design such a system is to have fewer partitions and use keyed messages to distribute the data over a fixed set of partitions. Me hace pensar que no es la herramienta adecuada para lo que describiste, pero además, ¿el tema sería "Eventos de vista de página"? Y todas las visitas a la página estarían en ese "tema". ¿Las particiones parecen más sobre paralelismo y réplicas y esas cosas? 11 de diciembre de 2017 a las 5:58
  • Gracias :) Finalmente tengo una respuesta: P 24 de enero de 2018 a las 8:35
64

Una vez que sepa cómo particionar su flujo de eventos, el nombre del tema será fácil, así que respondamos esa pregunta primero.

@Ludd es correcto: la estructura de partición que elija dependerá en gran medida de cómo desee procesar el flujo de eventos. Idealmente, desea una clave de partición, lo que significa que el procesamiento de su evento es local para la partición .

Por ejemplo:

  1. Si le preocupa el tiempo promedio de permanencia en el sitio de los usuarios, entonces debe dividir por :user-id. De esa manera, todos los eventos relacionados con la actividad del sitio de un solo usuario estarán disponibles dentro de la misma partición. Esto significa que un motor de procesamiento de flujo como Apache Samza puede calcular el tiempo promedio en el sitio para un usuario determinado con solo mirar los eventos en una sola partición. Esto evita tener que realizar cualquier tipo de procesamiento costoso de partición global.
  2. Si le interesan las páginas más populares de su sitio web, debe dividirlas por :viewedpágina. Nuevamente, Samza podrá llevar un recuento de las vistas de una página determinada con solo mirar los eventos en una sola partición.

En general, intentamos evitar tener que depender del estado global (como mantener recuentos en una base de datos remota como DynamoDB o Cassandra) y, en su lugar, poder trabajar utilizando el estado local de la partición. Esto se debe a que el estado local es una primitiva fundamental en el procesamiento de flujos .

Si necesita los dos casos de uso anteriores, entonces un patrón común con Kafka es primero particionar por ejemplo :user-id, y luego volver a particionar para estar :viewedlisto para la siguiente fase de procesamiento.

En cuanto a los nombres de los temas, uno obvio aquí sería eventso user-events. Para ser más específico, podría ir con events-by-user-idy / o events-by-viewed.

1
  • 8
    He visto referencias en las que publicaría los eventos en dos temas: uno por trabajador / uso previsto. En este caso, podría haber dos temas, con dos esquemas de particionamiento diferentes. 7 de agosto de 2015 a las 13:46
8

Esto no está exactamente relacionado con la pregunta, pero en caso de que ya haya decidido la segregación lógica de registros basada en temas y desee optimizar el recuento de temas / particiones en Kafka, esta publicación de blog puede ser útil.

Conclusiones clave en pocas palabras:

  • En general, cuantas más particiones haya en un clúster de Kafka, mayor será el rendimiento que se puede lograr. Sea py el máximo alcanzable en una sola partición para la producción y c . Digamos que su rendimiento objetivo es t . Entonces necesita tener al menos particiones máximas ( t / p , t / c ).

  • Actualmente, en Kafka, cada corredor abre un identificador de archivo tanto del índice como del archivo de datos de cada segmento de registro. Por lo tanto, cuantas más particiones, mayor es la necesidad de configurar el límite de manejo de archivos abiertos en el sistema operativo subyacente. Por ejemplo, en nuestro sistema de producción, una vez vimos un mensaje de error too many files are open, mientras que teníamos alrededor de 3600 particiones de tema.

  • Cuando un corredor se cierra de manera no limpia (por ejemplo, kill -9), la indisponibilidad observada podría ser proporcional al número de particiones.

  • La latencia de un extremo a otro en Kafka se define por el tiempo desde que el productor publica un mensaje hasta que el consumidor lee el mensaje. Como regla general, si le preocupa la latencia, probablemente sea una buena idea limitar el número de particiones por intermediario a 100 x b x r , donde b es el número de intermediarios en un clúster de Kafka y r es el factor de replicación.

5

Creo que el nombre del tema es una conclusión de un tipo de mensajes, y el productor publica el mensaje en el tema y el consumidor se suscribe a través del tema de suscripción.

Un tema puede tener muchas particiones. la partición es buena para el paralelismo. La partición también es la unidad de replicación, por lo que en Kafka, líder y seguidor también se dice en el nivel de partición. En realidad, una partición es una cola ordenada cuyo orden es el orden de llegada del mensaje. Y el tema está compuesto por una o más colas en una simple palabra. Esto nos resulta útil para modelar nuestra estructura.

Kafka es desarrollado por LinkedIn para la agregación y entrega de registros. esta escena es muy buena como ejemplo.

Su servidor web puede registrar los eventos del usuario en su web o aplicación y luego enviarlos al corredor de Kafka a través del productor. En el productor, puede especificar el método de partición, por ejemplo: tipo de evento (un evento diferente se guarda en una partición diferente) o tiempo del evento (dividir un día en un período diferente según la lógica de su aplicación) o el tipo de usuario o simplemente sin lógica y equilibrar todos los registros en muchas particiones.

Acerca de su caso en cuestión, puede crear un tema llamado "evento de vista de página" y crear N particiones a través de claves hash para distribuir los registros en todas las particiones de manera uniforme. O puede elegir una lógica de partición para hacer que el registro se distribuya según su espíritu.