ApsaraDB for ClickHouse es compatible con cuatro familias de motores de tablas: MergeTree, Log, Integrations y Special. Cada familia está optimizada para un conjunto diferente de cargas de trabajo. Este tema describe la función de cada motor y presenta ejemplos de los motores más utilizados.
Resumen de las familias de motores
|
Familia |
Ideal para |
Motores |
|
MergeTree |
Inserciones de alto rendimiento con procesamiento en segundo plano, particionamiento y replicación |
MergeTree, ReplacingMergeTree, CollapsingMergeTree, VersionedCollapsingMergeTree, SummingMergeTree, AggregatingMergeTree, GraphiteMergeTree, Índices de búsqueda de vecinos más cercanos aproximados, Búsqueda de texto completo mediante índices invertidos |
|
Log |
Escrituras rápidas en tablas pequeñas (~1 millón de filas) con lecturas de tabla completa |
TinyLog, StripeLog, Log |
|
Integrations |
Importación o consulta de orígenes de datos externos |
Kafka, MySQL, JDBC, ODBC, HDFS |
|
Special |
Necesidades arquitectónicas específicas (consultas distribuidas, vistas materializadas, tablas en memoria) |
Distributed, MaterializedView, Dictionary, Merge, File, NULL, Set, Join, URL, View, Memory, Buffer |
Para obtener una referencia completa de todos los motores de tablas compatibles, consulte Table Engines.
Familia MergeTree
Los motores de la familia MergeTree son la opción principal para cargas de trabajo en producción. Admiten inserciones de alta velocidad, particionamiento de datos, índices de clave primaria, índices dispersos, muestreo de datos, replicación de datos y tiempo de vida (TTL) para los datos.
Todos los motores MergeTree comparten la misma estructura de almacenamiento: los datos se escriben en partes y se fusionan en segundo plano, de forma similar a un árbol de fusión estructurado por registro (árbol LSM). El procesamiento en la capa de almacenamiento —incluida la deduplicación, el colapso y la agregación— ocurre durante la compactación, no al momento de la inserción.
MergeTree en ApsaraDB for ClickHouse es compatible con toda la sintaxis SQL de ClickHouse, pero las claves primarias funcionan de manera distinta al SQL estándar. La clave primaria acelera las consultas en lugar de imponer unicidad. Pueden existir claves primarias duplicadas incluso después de la compactación.
MergeTree
MergeTree es el motor base para cargas de trabajo de inserción con alta demanda. Los datos se insertan en partes y se fusionan en segundo plano según el orden de clasificación definido por ORDER BY.
Ejemplo: MergeTree con particionamiento
-
Cree una tabla particionada por
create_timey ordenada por(id, create_time).CREATE TABLE test_tbl ON CLUSTER default ( id UInt16, create_time Date, comment Nullable(String) ) ENGINE = MergeTree() PARTITION BY create_time ORDER BY (id, create_time) PRIMARY KEY (id, create_time) SETTINGS index_granularity=8192; -
Inserte filas con claves primarias duplicadas.
INSERT INTO test_tbl VALUES (1, '2019-12-13', null); INSERT INTO test_tbl VALUES (1, '2019-12-13', null); INSERT INTO test_tbl VALUES (2, '2019-12-14', null); INSERT INTO test_tbl VALUES (3, '2019-12-15', null); INSERT INTO test_tbl VALUES (3, '2019-12-15', null); -
Consulte la tabla.
SELECT * FROM test_tbl;Resultado: se devuelven las cinco filas, incluidos los duplicados:
┌─id─┬─create_time─┬─comment──┐ │ 1 │ 2019-12-13 │ NULL │ │ 1 │ 2019-12-13 │ NULL │ │ 2 │ 2019-12-14 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ └────┴─────────────┴──────────┘ -
Fuerce la compactación.
OPTIMIZE TABLE test_tbl FINAL; -
Vuelva a consultar.
SELECT * FROM test_tbl;Resultado: los duplicados siguen presentes. MergeTree no los elimina.
┌─id─┬─create_time─┬─comment──┐ │ 1 │ 2019-12-13 │ NULL │ │ 1 │ 2019-12-13 │ NULL │ │ 2 │ 2019-12-14 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ └────┴─────────────┴──────────┘
Para obtener más información, consulte MergeTree.
ReplacingMergeTree
ReplacingMergeTree elimina filas duplicadas con la misma clave primaria durante la compactación en segundo plano. Utilícelo cuando sea aceptable una deduplicación eventual, ya que no garantiza unicidad al momento de la consulta.
Limitaciones
En un clúster distribuido, las filas con la misma clave primaria pueden ubicarse en diferentes shards. La deduplicación solo ocurre dentro de un solo shard, no entre varios shards.
Antes de que finalice la compactación, algunos duplicados pueden seguir presentes. La compactación se ejecuta en segundo plano con una programación impredecible.
En conjuntos de datos grandes, ejecutar manualmente
OPTIMIZE ... FINALpuede tardar mucho tiempo, lo que hace impráctica la deduplicación en tiempo real.
Para obtener más información, consulte ReplacingMergeTree.
Ejemplo: Deduplicación con ReplacingMergeTree
-
Cree una tabla.
CREATE TABLE test_tbl_replacing ( id UInt16, create_time Date, comment Nullable(String) ) ENGINE = ReplacingMergeTree() PARTITION BY create_time ORDER BY (id, create_time) PRIMARY KEY (id, create_time) SETTINGS index_granularity=8192; -
Inserte filas con claves primarias duplicadas.
INSERT INTO test_tbl_replacing VALUES (1, '2019-12-13', null); INSERT INTO test_tbl_replacing VALUES (1, '2019-12-13', null); INSERT INTO test_tbl_replacing VALUES (2, '2019-12-14', null); INSERT INTO test_tbl_replacing VALUES (3, '2019-12-15', null); INSERT INTO test_tbl_replacing VALUES (3, '2019-12-15', null); -
Consulte antes de la compactación: los duplicados siguen presentes.
SELECT * FROM test_tbl_replacing;┌─id─┬─create_time─┬─comment──┐ │ 1 │ 2019-12-13 │ NULL │ │ 1 │ 2019-12-13 │ NULL │ │ 2 │ 2019-12-14 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ └────┴─────────────┴──────────┘ -
Fuerce la compactación.
OPTIMIZE TABLE test_tbl_replacing FINAL; -
Vuelva a consultar: los duplicados se eliminaron.
SELECT * FROM test_tbl_replacing;┌─id─┬─create_time─┬─comment──┐ │ 1 │ 2019-12-13 │ NULL │ │ 2 │ 2019-12-14 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ └────┴─────────────┴──────────┘
CollapsingMergeTree
CollapsingMergeTree rastrea los cambios de estado de las filas mediante una columna Sign en lugar de actualizar las filas en su lugar, ya que las actualizaciones son costosas en el modelo de almacenamiento de solo anexión de ClickHouse. Cada fila se marca como fila de estado (Sign = 1) o fila de cancelación (Sign = -1). Durante la compactación, los pares de filas de estado y de cancelación con la misma clave primaria se colapsan y se eliminan.
Cómo funciona el colapso
Para actualizar el estado de una fila:
Inserte una fila de cancelación con
Sign = -1y los mismos valores de clave primaria que la fila que desea reemplazar.Inserte una nueva fila de estado con
Sign = 1y los valores actualizados.
Para eliminar el estado de una fila: inserte una fila de cancelación que coincida con la fila de estado original en todas las columnas excepto en Sign.
Notas de uso
Si las filas de estado y de cancelación se insertan fuera de orden —por ejemplo, si se inserta una fila de cancelación y luego su fila de estado correspondiente llega por separado— es posible que no se colapsen correctamente. Considere usar VersionedCollapsingMergeTree para manejar inserciones fuera de orden.
El colapso solo ocurre dentro de un solo shard. En un clúster distribuido, las filas con la misma clave primaria en diferentes nodos no se colapsan.
-
Antes de que finalice la compactación, coexisten las filas de estado y de cancelación. Al ejecutar consultas agregadas antes de la compactación, ajuste su SQL:
Reemplace
COUNT()porSUM(Sign)Reemplace
SUM(col)porSUM(col * Sign)
Para obtener más información, consulte CollapsingMergeTree.
Ejemplo: Actualizaciones de estado con CollapsingMergeTree
-
Cree una tabla con una columna
Sign.CREATE TABLE test_tbl_collapsing ( UserID UInt64, PageViews UInt8, Duration UInt8, Sign Int8 ) ENGINE = CollapsingMergeTree(Sign) ORDER BY UserID; -
Inserte la fila de estado inicial.
INSERT INTO test_tbl_collapsing VALUES (4324182021466249494, 5, 146, 1); -
Actualice el estado: inserte una fila de cancelación para el estado anterior y una nueva fila de estado.
NotaInserte la fila de cancelación y la nueva fila de estado en el mismo lote. Si inserta la fila de cancelación y luego la fila de estado en operaciones separadas, podrían llegar fuera de orden. En ese caso, incluso si se fuerza la compactación, las filas con la misma clave primaria no podrán colapsarse ni eliminarse.
INSERT INTO test_tbl_collapsing VALUES (4324182021466249494, 5, 146, -1), -- cancel old state (4324182021466249494, 6, 185, 1); -- new state -
Consulte antes de la compactación: las tres filas están presentes.
SELECT * FROM test_tbl_collapsing;┌────────UserID───────┬─PageViews─┬─Duration─┬─Sign──┐ │ 4324182021466249494 │ 5 │ 146 │ 1 │ │ 4324182021466249494 │ 5 │ 146 │ -1 │ │ 4324182021466249494 │ 6 │ 185 │ 1 │ └─────────────────────┴───────────┴──────────┴───────┘Para obtener resultados agregados correctos antes de la compactación, use expresiones que consideren
Sign:SELECT UserID, SUM(PageViews * Sign) AS PageViews, SUM(Duration * Sign) AS Duration FROM test_tbl_collapsing GROUP BY UserID HAVING SUM(Sign) > 0;┌────────UserID───────┬─PageViews─┬─Duration──┐ │ 4324182021466249494 │ 6 │ 185 │ └─────────────────────┴───────────┴───────────┘ -
Fuerce la compactación.
OPTIMIZE TABLE test_tbl_collapsing FINAL; -
Vuelva a consultar: solo permanece la última fila de estado.
SELECT * FROM test_tbl_collapsing;┌────────UserID───────┬─PageViews─┬─Duration─┬─Sign──┐ │ 4324182021466249494 │ 6 │ 185 │ 1 │ └─────────────────────┴───────────┴──────────┴───────┘
VersionedCollapsingMergeTree
VersionedCollapsingMergeTree extiende CollapsingMergeTree con una columna Version que permite al motor emparejar correctamente las filas de estado y de cancelación sin importar el orden de inserción. Durante la compactación, se colapsan y eliminan las filas que tienen la misma clave primaria, el mismo valor de Version y valores opuestos de Sign.
Utilice este motor cuando las filas puedan llegar fuera de orden; por ejemplo, en pipelines basados en eventos donde los eventos de cancelación pueden procesarse antes que los eventos de estado a los que hacen referencia.
Al igual que con CollapsingMergeTree, ajuste las consultas agregadas para usar SUM(Sign) en lugar de COUNT() y SUM(col * Sign) en lugar de SUM(col).
Para obtener más información, consulte VersionedCollapsingMergeTree.
Ejemplo: VersionedCollapsingMergeTree con inserciones fuera de orden
-
Cree una tabla con columnas
SignyVersion.CREATE TABLE test_tbl_Versioned ( UserID UInt64, PageViews UInt8, Duration UInt8, Sign Int8, Version UInt8 ) ENGINE = VersionedCollapsingMergeTree(Sign, Version) ORDER BY UserID; -
Inserte primero una fila de cancelación (fuera de orden).
INSERT INTO test_tbl_Versioned VALUES (4324182021466249494, 5, 146, -1, 1); -
Inserte la fila de estado correspondiente y una nueva fila de estado.
INSERT INTO test_tbl_Versioned VALUES (4324182021466249494, 5, 146, 1, 1), -- state row matching the cancel above (4324182021466249494, 6, 185, 1, 2); -- new state -
Consulte antes de la compactación.
SELECT * FROM test_tbl_Versioned;┌────────UserID───────┬─PageViews─┬─Duration─┬─Sign───┬Version─┐ │ 4324182021466249494 │ 5 │ 146 │ -1 │ 1 │ │ 4324182021466249494 │ 5 │ 146 │ 1 │ 1 │ │ 4324182021466249494 │ 6 │ 185 │ 1 │ 2 │ └─────────────────────┴───────────┴──────────┴────────┴────────┘Use agregaciones que consideren
Signpara obtener resultados correctos antes de la compactación:SELECT UserID, SUM(PageViews * Sign) AS PageViews, SUM(Duration * Sign) AS Duration FROM test_tbl_Versioned GROUP BY UserID HAVING SUM(Sign) > 0;┌────────UserID───────┬─PageViews─┬─Duration─┐ │ 4324182021466249494 │ 6 │ 185 │ └─────────────────────┴───────────┴──────────┘ -
Fuerce la compactación.
OPTIMIZE TABLE test_tbl_Versioned FINAL; -
Vuelva a consultar: la columna
Versionemparejó correctamente las filas de cancelación y de estado a pesar de la inserción fuera de orden.SELECT * FROM test_tbl_Versioned;┌────────UserID───────┬─PageViews─┬─Duration─┬─Sign───┬Version─┐ │ 4324182021466249494 │ 6 │ 185 │ 1 │ 2 │ └─────────────────────┴───────────┴──────────┴────────┴────────┘
SummingMergeTree
Se recomienda usar SummingMergeTree junto con MergeTree. Almacene los datos detallados sin procesar en una tabla MergeTree y utilice SummingMergeTree para resultados preagregados. Esto evita la pérdida de datos si la clave primaria está compuesta incorrectamente.
SummingMergeTree preagrega filas con la misma clave primaria en una sola fila mediante la suma de columnas numéricas. Esto reduce el almacenamiento y acelera las consultas agregadas.
Notas de uso
La preagregación ocurre durante la compactación en segundo plano, no al momento de la inserción. Es posible que algunos datos aún no estén agregados, por lo que siempre debe incluir una cláusula
GROUP BYconSUM()en sus consultas.Solo se suman las columnas numéricas. Las columnas de tipo cadena y otras columnas no numéricas que no forman parte de la clave primaria obtienen un valor arbitrario después de la agregación.
Para obtener más información, consulte SummingMergeTree.
Ejemplo: Preagregación con SummingMergeTree
-
Cree una tabla.
CREATE TABLE test_tbl_summing ( key UInt32, value UInt32 ) ENGINE = SummingMergeTree() ORDER BY key; -
Inserte filas (algunas comparten la misma clave).
INSERT INTO test_tbl_summing VALUES (1, 1), (1, 2), (2, 1); -
Consulte antes de la compactación: las filas aún no están agregadas.
SELECT * FROM test_tbl_summing;┌─key─┬value─┐ │ 1 │ 1 │ │ 1 │ 2 │ │ 2 │ 1 │ └─────┴──────┘ -
Fuerce la compactación.
OPTIMIZE TABLE test_tbl_summing FINAL; -
Consulte con
GROUP BYySUM()para obtener resultados correctos.SELECT key, SUM(value) FROM test_tbl_summing GROUP BY key;┌─key─┬value─┐ │ 1 │ 3 │ │ 2 │ 1 │ └─────┴──────┘
AggregatingMergeTree
AggregatingMergeTree es un motor de preagregación más flexible que admite cualquier función de agregación, no solo SUM. Utiliza el tipo de dato especial AggregateFunction y un patrón de consulta de dos fases:
Fase de escritura: use funciones con sufijo
-State(por ejemplo,sumState,uniqState) para almacenar estados intermedios de agregación.Fase de consulta: use funciones con sufijo
-Merge(por ejemplo,sumMerge,uniqMerge) para finalizar la agregación.
AggregatingMergeTree se utiliza de dos formas: con una vista materializada (que automatiza la fase de escritura) o directamente con columnas AggregateFunction.
Para obtener más información, consulte AggregatingMergeTree.
Ejemplo 1: AggregatingMergeTree con una vista materializada
-
Cree una tabla de detalles.
CREATE TABLE visits ( UserID UInt64, CounterID UInt8, StartDate Date, Sign Int8 ) ENGINE = CollapsingMergeTree(Sign) ORDER BY UserID; -
Cree una vista materializada que preagregue la tabla de detalles mediante funciones
-State.CREATE MATERIALIZED VIEW visits_agg_view ENGINE = AggregatingMergeTree() PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate) AS SELECT CounterID, StartDate, sumState(Sign) AS Visits, uniqState(UserID) AS Users FROM visits GROUP BY CounterID, StartDate; -
Inserte datos en la tabla de detalles. La vista materializada se actualiza automáticamente.
INSERT INTO visits VALUES (0, 0, '2019-11-11', 1); INSERT INTO visits VALUES (1, 1, '2019-11-12', 1); -
Consulte la vista materializada mediante funciones
-Merge.NotaUse
sumMergeyuniqMerge: las funciones simplessumyuniqno pueden procesar columnasAggregateFunctiony devolverán un error.SELECT StartDate, sumMerge(Visits) AS Visits, uniqMerge(Users) AS Users FROM visits_agg_view GROUP BY StartDate ORDER BY StartDate;┌──StartDate──┬─Visits─┬─Users──┐ │ 2019-11-11 │ 1 │ 1 │ │ 2019-11-12 │ 1 │ 1 │ └─────────────┴────────┴────────┘
Ejemplo 2: AggregatingMergeTree con columnas AggregateFunction
-
Cree una tabla de detalles.
CREATE TABLE detail_table ( CounterID UInt8, StartDate Date, UserID UInt64 ) ENGINE = MergeTree() PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate); -
Inserte datos.
INSERT INTO detail_table VALUES (0, '2019-11-11', 1); INSERT INTO detail_table VALUES (1, '2019-11-12', 1); -
Cree una tabla agregada con una columna
AggregateFunction.CREATE TABLE agg_table ( CounterID UInt8, StartDate Date, UserID AggregateFunction(uniq, UInt64) ) ENGINE = AggregatingMergeTree() PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate); -
Inserte datos agregados mediante
uniqState.NotaInserte mediante una instrucción
SELECTcon funciones-State. Una instrucción directaINSERT INTO ... VALUEScon valores sin procesar fallará con un error de tipo.INSERT INTO agg_table SELECT CounterID, StartDate, uniqState(UserID) FROM detail_table GROUP BY CounterID, StartDate; -
Consulte la tabla agregada mediante
uniqMerge.SELECT uniqMerge(UserID) AS state FROM agg_table GROUP BY CounterID, StartDate;┌─state─┐ │ 1 │ │ 1 │ └───────┘
Familia Log
Los motores de la familia Log están diseñados para escrituras rápidas en tablas pequeñas (alrededor de un millón de filas) donde se lee toda la tabla a la vez.
Características comunes de todos los motores Log:
Los datos se anexan al disco de forma secuencial
No hay compatibilidad con
DELETEniUPDATENo hay compatibilidad con índices
Los datos no se escriben de forma atómica
INSERTbloqueaSELECTen la misma tabla
|
Motor |
Lecturas simultáneas |
Diseño de almacenamiento |
Cuándo utilizarlo |
|
No |
Un archivo por columna |
Datos intermedios temporales donde el rendimiento no es crítico |
|
|
Sí |
Todas las columnas en un solo archivo |
Mayor rendimiento de consultas que TinyLog con menos manejadores de archivos |
|
|
Sí |
Un archivo por columna |
Mayor rendimiento de consultas que TinyLog con acceso por columna |
Familia Integrations
Los motores de la familia Integrations conectan ApsaraDB for ClickHouse con orígenes de datos externos, ya sea importando datos o consultándolos en su ubicación original.
|
Motor |
Descripción |
|
Kafka |
Lee datos de temas de Kafka hacia ApsaraDB for ClickHouse |
|
MySQL |
Consulta tablas de MySQL directamente desde ApsaraDB for ClickHouse mediante |
|
JDBC |
Se conecta a orígenes de datos mediante cadenas de conexión de Java Database Connectivity (JDBC) |
|
ODBC |
Se conecta a orígenes de datos mediante cadenas de conexión de Open Database Connectivity (ODBC) |
|
HDFS |
Lee archivos en un formato especificado desde Hadoop Distributed File System (HDFS) |
Familia Special
Los motores de la familia Special satisfacen necesidades arquitectónicas específicas.
|
Motor |
Descripción |
|
Distributed |
No almacena datos. Enruta consultas a múltiples shards y agrega los resultados. |
|
MaterializedView |
Almacena resultados de consultas precalculados. Se usa para crear vistas materializadas. |
|
Dictionary |
Expone datos de diccionario como una tabla consultable. |
|
Merge |
No almacena datos. Lee desde varias tablas simultáneamente como una unión virtual. |
|
File |
Usa un archivo local como almacén de datos. |
|
NULL |
Descarta todos los datos escritos. Las lecturas devuelven resultados vacíos. Útil como destino para vistas materializadas durante pruebas. |
|
Set |
Siempre almacena datos en memoria de acceso aleatorio (RAM). |
|
Join |
Almacena datos de unión en RAM para búsquedas rápidas. |
|
URL |
Lee y escribe en endpoints HTTP o HTTPS remotos. |
|
View |
Almacena una definición de consulta |
|
Memory |
Almacena datos en RAM. Los datos se pierden cuando se reinicia el servidor. Adecuado para tablas temporales con menos de 100 millones de filas y sin requisitos de persistencia de datos. De uso común para tablas temporales en ApsaraDB for ClickHouse. |
|
Buffer |
Almacena escrituras en búfer en la RAM y las descarga a una tabla de destino cuando se cumplen umbrales configurables. |