如何在 Google Cloud Bigtable 中设置未来的插入日期?尝试使用 TTL 计算它
Posted
技术标签:
【中文标题】如何在 Google Cloud Bigtable 中设置未来的插入日期?尝试使用 TTL 计算它【英文标题】:How to set a future insert date in Google Cloud Bigtable? Trying to calculate it using TTL 【发布时间】:2018-10-03 14:35:47 【问题描述】:我有一个只有一个列族的表,该列的 TTL 为 172800 SECONDS (2 DAYS),我需要在截止日期之前删除一些数据。如果我希望该值在 5 分钟内到期,我会计算到期时间并将插入日期设置为到期时间前 5 分钟。
我正在使用 HBase Client for Java 来执行此操作。
但价值似乎没有过期。有什么相同的建议吗?
我用cbt建表:
cbt createtable my_table families=cf1:maxage=2d
HColumnDescriptor:
NAME => 'cf1', BLOOMFILTER => 'ROW', VERSIONS => '2147483647', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => '172800 SECONDS (2 DAYS)', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'
Java 代码:
import com.google.cloud.bigtable.hbase.BigtableConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
public class BigTable
public static void main(String... args)
String projectId = "my-gcp-project-id";
String instanceId = "my-bigtable-instance-id";
String tableId = "my-table"; // my-bigtable-table-id
try (Connection connection = BigtableConfiguration.connect(projectId, instanceId))
try (Table table = connection.getTable(TableName.valueOf(tableId)))
HTableDescriptor hTableDescriptor = table.getTableDescriptor();
hTableDescriptor.setCompactionEnabled(true);
byte[] cf1 = Bytes.toBytes("cf1");
byte[] rk1 = Bytes.toBytes("rowkey1");
byte[] q1 = Bytes.toBytes("q1");
HColumnDescriptor cfDescriptor1 = hTableDescriptor.getFamily(cf1);
System.out.println("\n " + cfDescriptor1);
Calendar now = Calendar.getInstance();
Calendar now1 = Calendar.getInstance();
now1.setTime(now.getTime());
long nowMillis = now.getTimeInMillis(); // Current time
now.add(Calendar.SECOND, cfDescriptor1.getTimeToLive()); // Adding 172800 SECONDS (2 DAYS) to current time
long cfTTLMillis = now.getTimeInMillis(); // Time the values in the column family will expire at
now1.add(Calendar.SECOND, 300); // Adding 300 secs (5mins)
long expiry = now1.getTimeInMillis(); // Time the value should actually live
long creationTime = nowMillis + cfTTLMillis - expiry;
System.out.println("\n Date nowMillis:\t" + new Date(nowMillis) + "\n Date creationTime:\t" + new Date(creationTime) + "\n Date cfTTLMillis:\t" + new Date(cfTTLMillis));
//Add Data
Put p = new Put(rk1, creationTime);
p.addColumn(cf1, q1, Bytes.toBytes("CFExpiry_2d_ExpTime_5mins"));
//p.setTTL(creationtime); // What does this do?
table.put(p);
catch (IOException e)
e.printStackTrace();
计算日期:
Date nowMillis: Wed Oct 03 10:34:15 EDT 2018
Date creationTime: Fri Oct 05 10:29:15 EDT 2018
Date cfTTLMillis: Fri Oct 05 10:34:15 EDT 2018
使用正确的计算日期正确插入了值。但是好像没有过期?如果错了,请纠正我的概念。
编辑:
在日期计算中进行以下更正后,这些值确实会过期。
long nowMillis = System.currentTimeMillis() / 1000;
long cfTTLMillis = nowMillis - cfDescriptor1.getTimeToLive();
long creationTime = (cfTTLMillis + 300) * 1000;
【问题讨论】:
【参考方案1】:在发生压缩之前,Cloud Bigtable 不会对行进行垃圾收集。这可能会在预期到期后数小时(或可能几天)发生。
如果您想确保不读取本应过期的数据,请对读取的数据设置时间戳范围过滤器,以便查询中不会返回允许范围之外的值。
或者,您必须在返回数据后过滤掉它们,但在服务器端过滤掉它会更有效,这样客户端就不必下载或处理它。
【讨论】:
您似乎也在向后计算。比 timeNow 大 至少 2 天的值将被删除(最终,正如 Solomon 指出的那样)。这意味着您希望插入时间为 now-2d+以上是关于如何在 Google Cloud Bigtable 中设置未来的插入日期?尝试使用 TTL 计算它的主要内容,如果未能解决你的问题,请参考以下文章
在 Google Cloud Datastore 与 Google Cloud Bigtable 中存储用户事件历史记录
Google Cloud Bigtable HBase shell 连接挂起
抛开价格不谈,为啥要选择 Google Cloud Bigtable 而不是 Google Cloud Datastore?