Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 卡桑德拉+;Hector,在测试中强制压缩以检查是否删除了空行_Java_Cassandra_Integration Testing_Hector - Fatal编程技术网

Java 卡桑德拉+;Hector,在测试中强制压缩以检查是否删除了空行

Java 卡桑德拉+;Hector,在测试中强制压缩以检查是否删除了空行,java,cassandra,integration-testing,hector,Java,Cassandra,Integration Testing,Hector,我们想测试一下,如果一个列具有TTL(生存时间)属性,那么它最终将与包含它的空行一起从cassandra中完全删除 据我所知,测试这种行为的算法是 保存对象时,为列设置TTL 等待TTL时间过去后,检查返回值是否为空 等待GC_GRACE_秒perion通过 检查该行是否也被删除 我没有检查最后一项 正如我发现的(例如,或在其他地方),我需要运行压缩。类似的问题也被提了出来(例如),但我没有发现任何有帮助的东西,谷歌也没有太大帮助 所以问题是,我如何从集成测试中强制压缩(使用hector)以

我们想测试一下,如果一个列具有TTL(生存时间)属性,那么它最终将与包含它的空行一起从cassandra中完全删除

据我所知,测试这种行为的算法是

  • 保存对象时,为列设置TTL
  • 等待TTL时间过去后,检查返回值是否为空
  • 等待GC_GRACE_秒perion通过
  • 检查该行是否也被删除
我没有检查最后一项

正如我发现的(例如,或在其他地方),我需要运行压缩。类似的问题也被提了出来(例如),但我没有发现任何有帮助的东西,谷歌也没有太大帮助

所以问题是,我如何从集成测试中强制压缩(使用hector)以确保它的行为符合预期?还是有其他方法可以做到这一点

注意:截断柱族不是一个选项


详情如下

我的测试:

private static final String KEYSPACE = "KEYSPACE";
private static final String COLUMN_FAMILY = "COLUMN_FAMILY";

private static final int GC_CRACE_SECONDS = 5;

// sut
private CassandraService cassandraService;

// dependencies
private Cluster cluster = HFactory.getOrCreateCluster("tstCltr", 
    "localhost:9160");

private Keyspace keyspace;

@BeforeClass
public static void setupBeforeClass() {
    EmbeddedCassandraDaemon.getEmbeddedCassandraDaemon();
}

@Before
public void setUp() throws Exception {
    keyspace = createKeyspace(KEYSPACE, cluster, 
        new QuorumAllConsistencyLevelPolicy());
    cassandraService = new CassandraService(cluster, KEYSPACE, 
        COLUMN_FAMILY, GC_CRACE_SECONDS);
}

@Test
public void rowGetsRemovedAfterGCGraceSeconds() throws Exception {
    Object obj = "OBJECT";
    String rowKey = "key";
    String columnName = "columnName";
    logger.info("before persisting rows count is {}" + countRows());

    cassandraService.persistObjectWithTtl(rowKey, columnName, obj, 5);

    logger.info("after persisting rows count is {}" + countRows());

    Object value = retrieve(rowKey, columnName);
    assertNotNull(value);

    logger.info("before TTL passes rows count is {}" + countRows());

    TimeUnit.SECONDS.sleep(6);

    Object nullValue = retrieve(rowKey, columnName);
    assertNull(nullValue);

    logger.info("after TTL passes rows count is {}" + countRows());

    TimeUnit.SECONDS.sleep(10);

    logger.info("wait 10 more seconds... rows count is {}" + countRows());
    System.out.println("================================" + countRows());

    TimeUnit.SECONDS.sleep(120);

    int countRows = countRows();
    logger.info("wait 2 more minutes... rows count is {}" + countRows);
    assertEquals(0, countRows);
}
用于持久化的代码:

public void persistObjectWithTtl(Object rowKey, Object columnName, 
        Object obj, int ttl) {
    LOGGER.debug("Persist {} / {}", rowKey, columnName);
    HColumn<Object, Object> column = createColumn(columnName, obj, 
            SERIALIZER, SERIALIZER);
    column.setTtl(ttl);
    executeInsertion(rowKey, column);
}

private void executeInsertion(Object rowKey, HColumn<Object, Object> column) {
    Mutator<Object> mutator = createMutator(keyspace, SERIALIZER);
    mutator.addInsertion(rowKey, this.columnFamilyName, column);
    mutator.execute();
}
以及计算行数的代码:

public int countRows(){
int rowCount=100;
ObjectSerializer serializer=ObjectSerializer.get();
兰奇斯克里兰奇斯克里=
createRangeS切片器(键空间、序列化程序、,
序列化程序,序列化程序)
.setColumnFamily(列_族)
.setRange(null、null、false、10)
.setRowCount(rowCount);
对象lastKey=null;
int i=0;
while(true){
rangeSlicesQuery.setKeys(lastKey,null);
查询结果=
rangeSlicesQuery.execute();
OrderedRows rows=result.get();
迭代器rowsIterator=rows.Iterator();
if(lastKey!=null&&rowsIterator!=null){
rowsIterator.next();
}
while(rowsIterator.hasNext()){
Row=rowsIterator.next();
lastKey=row.getKey();
i++;
if(row.getColumnSicle().getColumns().isEmpty()){
继续;
}
}
if(rows.getCount()
谢谢


更新:

原因是数据量不足以运行压缩,因此我需要放入更多数据,并更频繁地将表刷新到磁盘。因此,我最终得到了以下测试用例:

@Test
public void rowGetsRemovedAfterGCGraceSeconds() throws Exception {
    final int expectedAmount = 50000;

    logger.info("before persisting rows count is {}", countRows());

    for (int i = 0; i < expectedAmount; i++) {
        String rowKey = RandomStringUtils.randomAlphanumeric(128);
        Object obj = RandomStringUtils.randomAlphanumeric(1000);
        cassandraService.persistObjectWithTtl(rowKey, COLUMN_NAME, obj, 20);

        if (i % 100 == 0) {
            StorageService.instance.forceTableFlush(KEYSPACE, COLUMN_FAMILY);
        }
    }

    logger.info("causing major compaction...");
    StorageService.instance.forceTableCompaction(KEYSPACE, COLUMN_FAMILY);
    logger.info("after major compaction rows count is {}", countRows());

    waitAtMost(Duration.TWO_MINUTES)
        .pollDelay(Duration.TWO_SECONDS)
        .pollInterval(Duration.ONE_HUNDRED_MILLISECONDS)
        .until(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                int countRows = countRows();
                logger.info("the rows count is {}", countRows);
                return countRows < expectedAmount;
            }
        });
}
@测试
public void rowGetsRemovedAfterGCGraceSeconds()引发异常{
最终预期装载量=50000;
info(“在持久化行计数之前,{}”,countRows());
对于(int i=0;i

完整代码:

因为您使用的是Java,所以可以使用org.apache.cassandra.db.StorageService
MBean的
forceTableCompression(keyspace,columnFamily)
方法通过JMX轻松地强制压缩。

我试图通过jconsole连接并导致压缩,但行仍然存在。我在日志中看到的是“compression.CompactionManager-COLUMN_FAMILY中没有要压缩的内容;如果您希望强制压缩单个sstables(例如,对于tombstone collection),请使用ForceUserDefinedCompression”。啊,您只需先刷新列族,然后。在同一MBean上有一个JMX方法:
forceTableFlush(keyspace,columnFamily)
。当我尝试首先刷新列族时,会收到相同的消息。原因是我没有放入足够的数据。当我增加这个数字时(加上你建议的刷新数据),我确实开始看到行被删除了。谢谢,泰勒。我更新了我的问题以包括最终的测试用例。
public int countRows() {
    int rowCount = 100;

    ObjectSerializer serializer = ObjectSerializer.get();
    RangeSlicesQuery<Object, Object, Object> rangeSlicesQuery =
            HFactory.createRangeSlicesQuery(keyspace, serializer, 
                serializer, serializer)
                    .setColumnFamily(COLUMN_FAMILY)
                    .setRange(null, null, false, 10)
                    .setRowCount(rowCount);

    Object lastKey = null;

    int i = 0;
    while (true) {
        rangeSlicesQuery.setKeys(lastKey, null);

        QueryResult<OrderedRows<Object, Object, Object>> result = 
            rangeSlicesQuery.execute();
        OrderedRows<Object, Object, Object> rows = result.get();
        Iterator<Row<Object, Object, Object>> rowsIterator = rows.iterator();

        if (lastKey != null && rowsIterator != null) {
            rowsIterator.next();
        }

        while (rowsIterator.hasNext()) {
            Row<Object, Object, Object> row = rowsIterator.next();
            lastKey = row.getKey();
            i++;

            if (row.getColumnSlice().getColumns().isEmpty()) {
                continue;
            }
        }

        if (rows.getCount() < rowCount) {
            break;
        }

    }

    return i;
}
@Test
public void rowGetsRemovedAfterGCGraceSeconds() throws Exception {
    final int expectedAmount = 50000;

    logger.info("before persisting rows count is {}", countRows());

    for (int i = 0; i < expectedAmount; i++) {
        String rowKey = RandomStringUtils.randomAlphanumeric(128);
        Object obj = RandomStringUtils.randomAlphanumeric(1000);
        cassandraService.persistObjectWithTtl(rowKey, COLUMN_NAME, obj, 20);

        if (i % 100 == 0) {
            StorageService.instance.forceTableFlush(KEYSPACE, COLUMN_FAMILY);
        }
    }

    logger.info("causing major compaction...");
    StorageService.instance.forceTableCompaction(KEYSPACE, COLUMN_FAMILY);
    logger.info("after major compaction rows count is {}", countRows());

    waitAtMost(Duration.TWO_MINUTES)
        .pollDelay(Duration.TWO_SECONDS)
        .pollInterval(Duration.ONE_HUNDRED_MILLISECONDS)
        .until(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                int countRows = countRows();
                logger.info("the rows count is {}", countRows);
                return countRows < expectedAmount;
            }
        });
}