¿Cómo encuentra Cassandra el nodo que contiene los datos?
cassandra-2.0 (3)
He leído bastantes artículos y muchas preguntas / respuestas sobre SO sobre Cassandra, pero todavía no puedo entender cómo Cassandra decide a qué nodo (s) debe ir cuando está leyendo los datos.
Primero, algunas suposiciones acerca de un clúster imaginario:
- Estrategia de replicación = simple
- Usando particionador aleatorio
- Grupo de 10 nodos
- Factor de replicación de 5
Esta es mi comprensión de cómo funcionan las escrituras basadas en varios artículos de Datastax y otras publicaciones de blog que he leído:
- El cliente envía los datos a un nodo aleatorio
- El nodo "aleatorio" se decide en función del hash MD5 de la clave principal.
Los datos se escriben en el commit_log y memtable y luego se propagan 4 veces (con RF = 5).
Los 4 nodos siguientes en el anillo se seleccionan y los datos se conservan en ellos.
Hasta ahora tan bueno.
Ahora la pregunta es, cuando el cliente envía una solicitud de lectura (por ejemplo, con CL = 3) al clúster, ¿cómo sabe Cassandra qué nodos (5 de cada 10 como el peor escenario) necesita contactar para obtener estos datos? Seguramente no va a los 10 nodos, ya que sería ineficiente.
¿Estoy en lo cierto al suponer que Cassandra volverá a hacer un hash MD5 de la clave principal (de la solicitud) y elegir el nodo de acuerdo con eso y luego recorrer el anillo?
Además, ¿cómo funciona el caso de topología de red? si tengo varios centros de datos, ¿cómo sabe Cassandra qué nodos en cada DC / Rack contienen los datos? Por lo que entiendo, solo el primer nodo es obvio (ya que el hash de la clave principal ha dado como resultado ese nodo explícitamente).
Lo siento si la pregunta no es muy clara y por favor agregue un comentario si necesita más detalles sobre mi pregunta.
Muchas gracias,
El cliente envía los datos a un nodo aleatorio
Puede parecer así, pero en realidad hay una forma no aleatoria de que su conductor elija un nodo para hablar. Este nodo se denomina "nodo coordinador" y se elige normalmente en función de tener la "distancia de red" más pequeña (más cercana). Las solicitudes de los clientes realmente pueden enviarse a cualquier nodo, y al principio se enviarán a los nodos que su controlador conoce. Pero una vez que se conecta y entiende la topología de su grupo, puede cambiar a un coordinador "más cercano".
Los nodos de su clúster intercambian información de topología entre sí mediante el Protocolo de Gossip . El gossiper se ejecuta cada segundo y garantiza que todos los nodos se mantengan actualizados con los datos de cualquier Snitch que haya configurado. El snitch realiza un seguimiento de a qué centros de datos y racks pertenece cada nodo.
De esta manera, el nodo coordinador también tiene datos sobre qué nodos son responsables de cada rango de token. Puede ver esta información ejecutando un nodetool ring
desde la línea de comandos. Aunque si está utilizando vnodos, será más difícil de determinar, ya que los datos de los 256 nodos virtuales (predeterminados) aparecerán rápidamente en la pantalla.
Así que digamos que tengo una tabla que estoy usando para hacer un seguimiento de los miembros de la tripulación del barco por su primer nombre, y supongamos que quiero buscar a Malcolm Reynolds. Ejecutando esta consulta:
SELECT token(firstname),firstname, id, lastname
FROM usersbyfirstname WHERE firstname=''Mal'';
... devuelve esta fila:
token(firstname) | firstname | id | lastname
----------------------+-----------+----+-----------
4016264465811926804 | Mal | 2 | Reynolds
Al ejecutar un nodetool ring
puedo ver qué nodo es responsable de este token:
192.168.1.22 rack1 Up Normal 348.31 KB 3976595151390728557
192.168.1.22 rack1 Up Normal 348.31 KB 4142666302960897745
O incluso más fácil, puedo usar los nodetool getendpoints
de nodetool getendpoints
para ver estos datos:
$ nodetool getendpoints usersbyfirstname Mal
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar
192.168.1.22
Para obtener más información, consulte algunos de los elementos vinculados anteriormente o intente ejecutar nodetool gossipinfo
.
Cassandra localizará todos los datos en función de una clave de partición que el particionador asigna a un valor de token. Los tokens son parte de un rango de valores de anillo token finito donde cada parte del anillo es propiedad de un nodo en el clúster. Se dice que el nodo que posee el rango de un determinado token es el primario para ese token. Las réplicas serán seleccionadas por la estrategia de replicación de datos. Básicamente esto funciona al ir en el sentido de las agujas del reloj en el token ring, comenzando desde el primario y parando dependiendo del número de réplicas requeridas.
Lo que es importante tener en cuenta es que cada nodo del clúster puede identificar los nodos responsables de una determinada clave en función de la lógica descrita anteriormente. Cuando se escribe un valor en el clúster, el nodo que acepta la solicitud (el nodo coordinador) conocerá de inmediato los nodos que necesitan ejecutar la escritura.
En el caso de múltiples centros de datos, todas las claves se asignarán en todos los DC al mismo token determinado por el particionador. Cassandra intentará escribir en cada DC y en las réplicas de cada DC.
Cassandra usa un hashing consistente para asignar cada clave de partición a un valor de token. Cada nodo posee rangos de valores de token como su rango principal , de modo que cada valor de hash posible se asignará a un nodo. Las réplicas adicionales se guardan de manera sistemática (como el siguiente nodo en el anillo) y se almacenan en los nodos como su rango secundario .
Cada nodo en el clúster conoce la topología de todo el clúster, por ejemplo, qué nodos están en qué centro de datos, dónde están en el anillo y qué rangos de token posee cada nodo. Los nodos obtienen y mantienen esta información usando el protocolo de chismes.
Cuando entra una solicitud de lectura, el nodo contactado se convierte en el coordinador de la lectura. Calculará qué nodos tienen réplicas para la partición solicitada y luego seleccionará el número requerido de nodos para cumplir con el nivel de consistencia. Luego enviará solicitudes a esos nodos, esperará sus respuestas y combinará los resultados en función de las marcas de tiempo de la columna antes de enviar el resultado al cliente.