database - tutorial - ultima version de apache cassandra
La mejor manera de almacenar el tiempo del Ășltimo toque en Cassandra (2)
Cassandra tiene soporte implícito para writetime
por cada columna. Mira esto , parece que eso es lo que estás buscando aquí.
Estoy almacenando un tiempo tocado por última vez en una tabla de usuarios en Postgres, pero hay muchas actualizaciones frecuentes y suficiente contención que puedo ver ejemplos de 3 de las mismas actualizaciones de bloqueo.
Cassandra parece una mejor opción para esto, pero ¿debería dedicarle una mesa solo para este propósito? Y no necesito marcas de tiempo antiguas, solo las últimas. ¿Debería usar algo que no sea Cassandra? Si debería usar Cassandra, ¿algún consejo sobre las propiedades de la tabla?
La mesa que tengo en mente:
CREATE TABLE ksp1.user_last_job_activities (
user_id bigint,
touched_at timeuuid,
PRIMARY KEY (user_id, touched_at)
) WITH CLUSTERING ORDER BY (touched_at DESC)
AND bloom_filter_fp_chance = 0.01
AND caching = ''{"keys":"ALL", "rows_per_partition":"NONE"}''
AND comment = ''''
AND compaction = {''min_threshold'': ''4'', ''class'': ''org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'', ''max_threshold'': ''32''}
AND compression = {''sstable_compression'': ''org.apache.cassandra.io.compress.LZ4Compressor''}
AND dclocal_read_repair_chance = 0.1
AND default_time_to_live = 0
AND gc_grace_seconds = 864000
AND max_index_interval = 2048
AND memtable_flush_period_in_ms = 0
AND min_index_interval = 128
AND read_repair_chance = 0.0
AND speculative_retry = ''99.0PERCENTILE'';
Actualizar
¡Gracias! Hice algunos experimentos en writetime y como tenía que escribir un valor de todos modos, escribí la hora.
Al igual que:
CREATE TABLE simple_user_last_activity (
user_id bigint,
touched_at timestamp,
PRIMARY KEY (user_id)
);
Entonces:
INSERT INTO simple_user_last_activity (user_id, touched_at) VALUES (6, dateof(now()));
SELECT touched_at from simple_user_last_activity WHERE user_id = 6;
Como touch_at ya no está en la clave principal, solo se almacena un registro por usuario.
Actualización 2
Hay otra opción con la que voy a ir. También puedo almacenar el job_id, que brinda más datos para el análisis:
CREATE TABLE final_user_last_job_activities (
user_id bigint,
touched_at timestamp,
job_id bigint,
PRIMARY KEY (user_id, touched_at)
)
WITH CLUSTERING ORDER BY (touched_at DESC)
AND default_time_to_live = 604800;
Agregar el TTL de 1 semana se ocupa de los registros caducados; si no hay ninguno, devuelvo la hora actual.
INSERT INTO final_user_last_job_activities (user_id, touched_at, job_id) VALUES (5, dateof(now()), 5);
INSERT INTO final_user_last_job_activities (user_id, touched_at, job_id) VALUES (5, dateof(now()), 6);
INSERT INTO final_user_last_job_activities (user_id, touched_at, job_id) VALUES (5, dateof(now()), 7);
INSERT INTO final_user_last_job_activities (user_id, touched_at, job_id) VALUES (5, dateof(now()), 6);
SELECT * FROM final_user_last_job_activities LIMIT 1;
Lo que me da:
user_id | touched_at | job_id
---------+--------------------------+--------
5 | 2015-06-17 12:43:30+1200 | 6
Los puntos de referencia simples no muestran una diferencia de rendimiento significativa en el almacenamiento o la lectura de la tabla más grande.
Como c * es la última escritura gana, simplemente puede mantener las últimas versiones de cada fila.
Podría, como sugiere MSD, usar writetime
para sacar el tiempo de la escritura. Pero tenga cuidado porque esto es específico de la columna y no puede usar el tiempo de escritura en sus columnas de clave principal. Por ejemplo, en una tabla de la siguiente manera:
cqlsh> create TABLE test.test ( a int, b int, c int, d int, primary key (a))
... ;
cqlsh> insert INTO test.test (a, b, c, d) VALUES ( 1,2,3,4)
... ;
cqlsh> select * from test.test
... ;
a | b | c | d
---+------+---+------
1 | 2 | 3 | 4
(2 rows)
cqlsh> insert into test.test (a,c) values (1, 6);
cqlsh> select * from test.test ;
a | b | c | d
---+------+---+------
1 | 2 | 6 | 4
(2 rows)
cqlsh> select writetime(a), writetime(b), writetime(c), writetime(d) from test.test
... ;
InvalidRequest: code=2200 [Invalid query] message="Cannot use selection function writeTime on PRIMARY KEY part a"
cqlsh> select writetime(b), writetime(c), writetime(d) from test.test ;
writetime(b) | writetime(c) | writetime(d)
------------------+------------------+------------------
1434424690700887 | 1434424690700887 | 1434424702420929
De lo contrario, puede agregar una columna cql con la marca de tiempo:
create TABLE test.test ( a int, b int, c int, d int, touched_at timeuuid, primary key (a)) ;
Algunas evaluaciones comparativas rápidas lo ayudarían a determinar cuál es más eficiente.