Cassandra consulta mucho el tiempo y lo agrega a memtable cuando las claves están completamente contraídas
cassandra-3.0 (2)
Estas comparando manzanas con naranjas
La primera consulta que está solicitando para todas las filas que coincidan con la condición
k1 = ''AAA'' and k2 = ''BBB'' and c1 = ''2017-09-05T16:09:00.222Z'' and c2 = ''CCC''
La condición adicional aquí es c2 = ''CCC'', entonces Cassandra necesita hacer más trabajo para devolver las filas que coincidan con esas condiciones.En la segunda consulta, está relajando la condición de coincidencia en c2, por lo tanto, puede ver diferentes comportamientos de rendimiento.
Supongamos que tiene 1000 filas que coinciden con la condición k1 = ''AAA'' y k2 = ''BBB'' y c1 = ''2017-09-05T16: 09: 00.222Z''. Agregar la condición para c2 podría devolver solo 4 filas (Puede ser necesario verificar todas las filas para la condición c2) donde al eliminar las condiciones comenzará a transmitir los resultados una vez que llegue a corresponder k1, k2 y c1.
- Si realmente desea comparar, puede comparar el rendimiento entre
k1 = ''AAA'' and k2 = ''BBB'' and c1 = ''2017-09-05T16:09:00.222Z'' and c2 = ''CCC'' OR k1 = ''AAA'' and k2 = ''BBB'' and c1 = ''2017-09-05T16:09:00.222Z'' and c2 = ''XXX''
Además, al comprobar el rendimiento, debe ejecutar la misma consulta varias veces para evitar comportamientos de almacenamiento en caché.
Tengo una mesa de Cassandra y las teclas se ven así:
PRIMARY KEY (("k1", "k2"), "c1", "c2"),) CON CLUSTERING ORDER BY ("c1" DESC, "c2" DESC);
Cuando restrinjo por completo una consulta, lleva mucho más tiempo que si dejo fuera la última clave de clúster. También preforma un "Adding to feed memtable" que la consulta no restringida no contiene. ¿Por qué es esto? Sé previamente que esta consulta no agregaría la entrada a la memtable ya que tengo un código personalizado en ejecución cuando se agregan cosas a la memtable. Este código solo debe ejecutarse cuando las cosas se insertan o modifican, pero comenzó a funcionar cuando solo estaba consultando elementos.
Editar: debería haber mencionado que ambas consultas devuelven 1 fila y es el mismo registro.
activity | timestamp | source | source_elapsed | client
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+---------------+----------------+------------
Execute CQL3 query | 2017-09-05 18:09:37.456000 | **.***.**.237 | 0 | ***.**.*.4
Parsing select c2 from feed where k1 = ''AAA'' and k2 = ''BBB'' and c1 = ''2017-09-05T16:09:00.222Z'' and c2 = ''CCC''; [SharedPool-Worker-1] | 2017-09-05 18:09:37.456000 | **.***.**.237 | 267 | ***.**.*.4
Preparing statement [SharedPool-Worker-1] | 2017-09-05 18:09:37.456000 | **.***.**.237 | 452 | ***.**.*.4
Executing single-partition query on feed [SharedPool-Worker-3] | 2017-09-05 18:09:37.457000 | **.***.**.237 | 1253 | ***.**.*.4
Acquiring sstable references [SharedPool-Worker-3] | 2017-09-05 18:09:37.457000 | **.***.**.237 | 1312 | ***.**.*.4
Merging memtable contents [SharedPool-Worker-3] | 2017-09-05 18:09:37.457000 | **.***.**.237 | 1370 | ***.**.*.4
Key cache hit for sstable 22 [SharedPool-Worker-3] | 2017-09-05 18:09:37.463000 | **.***.**.237 | 6939 | ***.**.*.4
Key cache hit for sstable 21 [SharedPool-Worker-3] | 2017-09-05 18:09:37.463000 | **.***.**.237 | 7077 | ***.**.*.4
Key cache hit for sstable 12 [SharedPool-Worker-3] | 2017-09-05 18:09:37.463000 | **.***.**.237 | 7137 | ***.**.*.4
Key cache hit for sstable 6 [SharedPool-Worker-3] | 2017-09-05 18:09:37.463000 | **.***.**.237 | 7194 | ***.**.*.4
Key cache hit for sstable 3 [SharedPool-Worker-3] | 2017-09-05 18:09:37.463000 | **.***.**.237 | 7249 | ***.**.*.4
Merging data from sstable 10 [SharedPool-Worker-3] | 2017-09-05 18:09:37.463000 | **.***.**.237 | 7362 | ***.**.*.4
Key cache hit for sstable 10 [SharedPool-Worker-3] | 2017-09-05 18:09:37.463001 | **.***.**.237 | 7429 | ***.**.*.4
Key cache hit for sstable 9 [SharedPool-Worker-3] | 2017-09-05 18:09:37.463001 | **.***.**.237 | 7489 | ***.**.*.4
Key cache hit for sstable 4 [SharedPool-Worker-3] | 2017-09-05 18:09:37.463001 | **.***.**.237 | 7628 | ***.**.*.4
Key cache hit for sstable 7 [SharedPool-Worker-3] | 2017-09-05 18:09:37.463001 | **.***.**.237 | 7720 | ***.**.*.4
Defragmenting requested data [SharedPool-Worker-3] | 2017-09-05 18:09:37.463001 | **.***.**.237 | 7779 | ***.**.*.4
Adding to feed memtable [SharedPool-Worker-4] | 2017-09-05 18:09:37.464000 | **.***.**.237 | 7896 | ***.**.*.4
Read 1 live and 4 tombstone cells [SharedPool-Worker-3] | 2017-09-05 18:09:37.464000 | **.***.**.237 | 7932 | ***.**.*.4
Request complete | 2017-09-05 18:09:37.464092 | **.***.**.237 | 8092 | ***.**.*.4
activity | timestamp | source | source_elapsed | client
-------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+---------------+----------------+------------
Execute CQL3 query | 2017-09-05 18:09:44.703000 | **.***.**.237 | 0 | ***.**.*.4
Parsing select c2 from feed where k1 = ''AAA'' and k2 = ''BBB'' and c1 = ''2017-09-05T16:09:00.222Z''; [SharedPool-Worker-1] | 2017-09-05 18:09:44.704000 | **.***.**.237 | 508 | ***.**.*.4
Preparing statement [SharedPool-Worker-1] | 2017-09-05 18:09:44.704000 | **.***.**.237 | 717 | ***.**.*.4
Executing single-partition query on feed [SharedPool-Worker-2] | 2017-09-05 18:09:44.704000 | **.***.**.237 | 1377 | ***.**.*.4
Acquiring sstable references [SharedPool-Worker-2] | 2017-09-05 18:09:44.705000 | **.***.**.237 | 1499 | ***.**.*.4
Key cache hit for sstable 10 [SharedPool-Worker-2] | 2017-09-05 18:09:44.705000 | **.***.**.237 | 1730 | ***.**.*.4
Skipped 8/9 non-slice-intersecting sstables, included 5 due to tombstones [SharedPool-Worker-2] | 2017-09-05 18:09:44.705000 | **.***.**.237 | 1804 | ***.**.*.4
Key cache hit for sstable 22 [SharedPool-Worker-2] | 2017-09-05 18:09:44.705000 | **.***.**.237 | 1858 | ***.**.*.4
Key cache hit for sstable 21 [SharedPool-Worker-2] | 2017-09-05 18:09:44.705000 | **.***.**.237 | 1908 | ***.**.*.4
Key cache hit for sstable 12 [SharedPool-Worker-2] | 2017-09-05 18:09:44.705000 | **.***.**.237 | 1951 | ***.**.*.4
Key cache hit for sstable 6 [SharedPool-Worker-2] | 2017-09-05 18:09:44.705001 | **.***.**.237 | 2002 | ***.**.*.4
Key cache hit for sstable 3 [SharedPool-Worker-2] | 2017-09-05 18:09:44.705001 | **.***.**.237 | 2037 | ***.**.*.4
Merged data from memtables and 6 sstables [SharedPool-Worker-2] | 2017-09-05 18:09:44.705001 | **.***.**.237 | 2252 | ***.**.*.4
Read 1 live and 4 tombstone cells [SharedPool-Worker-2] | 2017-09-05 18:09:44.705001 | **.***.**.237 | 2307 | ***.**.*.4
Request complete | 2017-09-05 18:09:44.705458 | **.***.**.237 | 2458 | ***.**.*.4
cqlsh> show version [cqlsh 5.0.1 | Cassandra 3.7 | CQL spec 3.4.2 | Native protocol v4]
Esta es una gran pregunta, y usted (amablemente) proporcionó toda la información que necesitamos para responderla.
Su primera consulta es una búsqueda de puntos (porque especifica ambas claves de agrupamiento). El segundo es un corte.
Si miramos el rastro, la diferencia obvia en su rastro es:
Skipped 8/9 non-slice-intersecting sstables, included 5 due to tombstones
Esa es una muy buena pista de que estamos tomando dos caminos de lectura diferentes. Podrías usarlo para codificar la inmersión, pero a corto plazo, el filtro que utilizas para tu lectura de puntos significa que consultarás las tablas / tablas variables en orden diferente - para las lecturas de puntos, ordenamos por marca de tiempo, para cortar, intentaremos para eliminar sstables que no se intersectan primero.
Los comentarios en el código insinúan eso - para el primero:
/**
* Do a read by querying the memtable(s) first, and then each relevant sstables sequentially by order of the sstable
* max timestamp.
*
* This is used for names query in the hope of only having to query the 1 or 2 most recent query and then knowing nothing
* more recent could be in the older sstables (which we can only guarantee if we know exactly which row we queries, and if
* no collection or counters are included).
* This method assumes the filter is a {@code ClusteringIndexNamesFilter}.
*/
Y el segundo:
/*
* We have 2 main strategies:
* 1) We query memtables and sstables simulateneously. This is our most generic strategy and the one we use
* unless we have a names filter that we know we can optimize futher.
* 2) If we have a name filter (so we query specific rows), we can make a bet: that all column for all queried row
* will have data in the most recent sstable(s), thus saving us from reading older ones. This does imply we
* have a way to guarantee we have all the data for what is queried, which is only possible for name queries
* and if we have neither collections nor counters (indeed, for a collection, we can''t guarantee an older sstable
* won''t have some elements that weren''t in the most recent sstables, and counters are intrinsically a collection
* of shards so have the same problem).
*/
En su caso, si la fila devuelta estaba en la memoria, la primera lectura (punto) sería más rápida. Además, dado que tiene 8 inestables, es probable que use STCS o TWCS; si usó LCS, es probable que compacte esa partición en ~ 5 elementos inestables y que (nuevamente) tenga un rendimiento de lectura más predecible.
Sé previamente que esta consulta no agregaría la entrada a la memtable ya que tengo un código personalizado en ejecución cuando se agregan cosas a la memtable. Este código solo debe ejecutarse cuando las cosas se insertan o modifican, pero comenzó a funcionar cuando solo estaba consultando elementos.
Ninguna de las vías de lectura debe agregar nada a la variable de forma predeterminada, a menos que se le haya reparado (es decir, a menos que los valores no coincidan entre las réplicas o la probabilidad de reparación de lectura de fondo se active). Tenga en cuenta que es mucho más probable que una consulta de sector no coincida con una consulta de punto, porque está basada en el análisis, usted podrá leer, reparar cualquiera / todos los marcadores de eliminación (lápidas) con valores coincidentes de c1 = ''2017-09-05T16:09:00.222Z''
Editar: Perdí una línea en la traza:
Defragmenting requested data
Es una indicación de que está usando STCS y tocó demasiados elementos inestables, por lo que toda la partición se copió en la memoria para que las lecturas futuras sean más rápidas. Esa es una optimización poco conocida en STCS cuando empiezas a tocar demasiados elementos inestables, puedes evitarlo usando LCS.