Search in sources :

Example 1 with GuavaCacheTable

use of org.apache.samza.table.caching.guava.GuavaCacheTable in project samza by apache.

the class CachingTableProvider method createDefaultCacheTable.

private ReadWriteUpdateTable createDefaultCacheTable(String tableId, JavaTableConfig tableConfig) {
    long readTtlMs = Long.parseLong(tableConfig.getForTable(tableId, CachingTableDescriptor.READ_TTL_MS, "-1"));
    long writeTtlMs = Long.parseLong(tableConfig.getForTable(tableId, CachingTableDescriptor.WRITE_TTL_MS, "-1"));
    long cacheSize = Long.parseLong(tableConfig.getForTable(tableId, CachingTableDescriptor.CACHE_SIZE, "-1"));
    CacheBuilder cacheBuilder = CacheBuilder.newBuilder();
    if (readTtlMs != -1) {
        cacheBuilder.expireAfterAccess(readTtlMs, TimeUnit.MILLISECONDS);
    }
    if (writeTtlMs != -1) {
        cacheBuilder.expireAfterWrite(writeTtlMs, TimeUnit.MILLISECONDS);
    }
    if (cacheSize != -1) {
        cacheBuilder.maximumSize(cacheSize);
    }
    logger.info(String.format("Creating default cache with: readTtl=%d, writeTtl=%d, maxSize=%d", readTtlMs, writeTtlMs, cacheSize));
    GuavaCacheTable cacheTable = new GuavaCacheTable(tableId + "-def-cache", cacheBuilder.build());
    cacheTable.init(this.context);
    return cacheTable;
}
Also used : CacheBuilder(com.google.common.cache.CacheBuilder) GuavaCacheTable(org.apache.samza.table.caching.guava.GuavaCacheTable)

Example 2 with GuavaCacheTable

use of org.apache.samza.table.caching.guava.GuavaCacheTable in project samza by apache.

the class TestCachingTable method testTimerDisabled.

@Test
public void testTimerDisabled() throws Exception {
    String tableId = "testTimerDisabled";
    Cache<String, String> guavaCache = CacheBuilder.newBuilder().initialCapacity(100).build();
    final ReadWriteUpdateTable<String, String, String> guavaTable = new GuavaCacheTable<>(tableId, guavaCache);
    TableRateLimiter<String, String> readRateLimitHelper = mock(TableRateLimiter.class);
    TableRateLimiter<String, String> writeRateLimitHelper = mock(TableRateLimiter.class);
    TableRateLimiter<String, String> updateRateLimitHelper = mock(TableRateLimiter.class);
    TableReadFunction<String, String> readFn = mock(TableReadFunction.class);
    doReturn(CompletableFuture.completedFuture("")).when(readFn).getAsync(any());
    TableWriteFunction<String, String, String> writeFn = mock(TableWriteFunction.class);
    doReturn(CompletableFuture.completedFuture(null)).when(writeFn).putAsync(any(), any());
    doReturn(CompletableFuture.completedFuture(null)).when(writeFn).deleteAsync(any());
    final RemoteTable<String, String, String> remoteTable = new RemoteTable<>(tableId, readFn, writeFn, readRateLimitHelper, writeRateLimitHelper, updateRateLimitHelper, Executors.newSingleThreadExecutor(), null, null, null, null, null, Executors.newSingleThreadExecutor());
    final CachingTable<String, String, String> cachingTable = new CachingTable<>(tableId, remoteTable, guavaTable, false);
    initTables(true, cachingTable, guavaTable, remoteTable);
    cachingTable.get("");
    cachingTable.getAsync("").get();
    cachingTable.getAll(Collections.emptyList());
    cachingTable.getAllAsync(Collections.emptyList());
    cachingTable.flush();
    cachingTable.put("", "");
    cachingTable.putAsync("", "");
    cachingTable.putAll(Collections.emptyList());
    cachingTable.putAllAsync(Collections.emptyList());
    cachingTable.delete("");
    cachingTable.deleteAsync("");
    cachingTable.deleteAll(Collections.emptyList());
    cachingTable.deleteAllAsync(Collections.emptyList());
}
Also used : RemoteTable(org.apache.samza.table.remote.RemoteTable) GuavaCacheTable(org.apache.samza.table.caching.guava.GuavaCacheTable) Matchers.anyString(org.mockito.Matchers.anyString) Test(org.junit.Test)

Example 3 with GuavaCacheTable

use of org.apache.samza.table.caching.guava.GuavaCacheTable in project samza by apache.

the class TestCachingTable method testGuavaCacheAndRemoteTable.

/**
 * Testing caching in a more realistic scenario with Guava cache + remote table
 */
@Test
public void testGuavaCacheAndRemoteTable() throws Exception {
    String tableId = "testGuavaCacheAndRemoteTable";
    Cache<String, String> guavaCache = CacheBuilder.newBuilder().initialCapacity(100).build();
    final ReadWriteUpdateTable<String, String, String> guavaTable = new GuavaCacheTable<>(tableId + "-cache", guavaCache);
    // It is okay to share rateLimitHelper and async helper for read/write in test
    TableRateLimiter<String, String> readRateLimitHelper = mock(TableRateLimiter.class);
    TableRateLimiter<String, String> writeRateLimitHelper = mock(TableRateLimiter.class);
    TableRateLimiter<String, String> updateRateLimitHelper = mock(TableRateLimiter.class);
    TableReadFunction<String, String> readFn = mock(TableReadFunction.class);
    TableWriteFunction<String, String, String> writeFn = mock(TableWriteFunction.class);
    final RemoteTable<String, String, String> remoteTable = new RemoteTable<>(tableId + "-remote", readFn, writeFn, readRateLimitHelper, writeRateLimitHelper, updateRateLimitHelper, Executors.newSingleThreadExecutor(), null, null, null, null, null, Executors.newSingleThreadExecutor());
    final CachingTable<String, String, String> cachingTable = new CachingTable<>(tableId, remoteTable, guavaTable, false);
    initTables(cachingTable, guavaTable, remoteTable);
    // 4 per readable table (12)
    // 8 per read/write table (24)
    verify(metricsRegistry, times(36)).newCounter(any(), anyString());
    // 3 per readable table (9)
    // 8 per read/write table (24)
    // 1 per remote readable table (1)
    // 2 per remote read/write table (2)
    verify(metricsRegistry, times(36)).newTimer(any(), anyString());
    // 1 per guava table (1)
    // 3 per caching table (2)
    verify(metricsRegistry, times(4)).newGauge(anyString(), any());
    // GET
    doReturn(CompletableFuture.completedFuture("bar")).when(readFn).getAsync(any());
    Assert.assertEquals(cachingTable.getAsync("foo").get(), "bar");
    // Ensure cache is updated
    Assert.assertEquals(guavaCache.getIfPresent("foo"), "bar");
    // PUT
    doReturn(CompletableFuture.completedFuture(null)).when(writeFn).putAsync(any(), any());
    cachingTable.putAsync("foo", "baz").get();
    // Ensure cache is updated
    Assert.assertEquals(guavaCache.getIfPresent("foo"), "baz");
    // DELETE
    doReturn(CompletableFuture.completedFuture(null)).when(writeFn).deleteAsync(any());
    cachingTable.deleteAsync("foo").get();
    // Ensure cache is updated
    Assert.assertNull(guavaCache.getIfPresent("foo"));
    // GET-ALL
    Map<String, String> records = new HashMap<>();
    records.put("foo1", "bar1");
    records.put("foo2", "bar2");
    doReturn(CompletableFuture.completedFuture(records)).when(readFn).getAllAsync(any());
    Assert.assertEquals(cachingTable.getAllAsync(Arrays.asList("foo1", "foo2")).get(), records);
    // Ensure cache is updated
    Assert.assertEquals(guavaCache.getIfPresent("foo1"), "bar1");
    Assert.assertEquals(guavaCache.getIfPresent("foo2"), "bar2");
    // GET-ALL with partial miss
    doReturn(CompletableFuture.completedFuture(Collections.singletonMap("foo3", "bar3"))).when(readFn).getAllAsync(any());
    records = cachingTable.getAllAsync(Arrays.asList("foo1", "foo2", "foo3")).get();
    Assert.assertEquals(records.get("foo3"), "bar3");
    // Ensure cache is updated
    Assert.assertEquals(guavaCache.getIfPresent("foo3"), "bar3");
    // Calling again for the same keys should not trigger IO, ie. no exception is thrown
    CompletableFuture<String> exFuture = new CompletableFuture<>();
    exFuture.completeExceptionally(new RuntimeException("Test exception"));
    doReturn(exFuture).when(readFn).getAllAsync(any());
    cachingTable.getAllAsync(Arrays.asList("foo1", "foo2", "foo3")).get();
    // Partial results should throw
    try {
        cachingTable.getAllAsync(Arrays.asList("foo1", "foo2", "foo5")).get();
        Assert.fail();
    } catch (Exception e) {
    }
    // PUT-ALL
    doReturn(CompletableFuture.completedFuture(null)).when(writeFn).putAllAsync(any());
    List<Entry<String, String>> entries = new ArrayList<>();
    entries.add(new Entry<>("foo1", "bar111"));
    entries.add(new Entry<>("foo2", "bar222"));
    cachingTable.putAllAsync(entries).get();
    // Ensure cache is updated
    Assert.assertEquals(guavaCache.getIfPresent("foo1"), "bar111");
    Assert.assertEquals(guavaCache.getIfPresent("foo2"), "bar222");
    // PUT-ALL with delete
    doReturn(CompletableFuture.completedFuture(null)).when(writeFn).putAllAsync(any());
    doReturn(CompletableFuture.completedFuture(null)).when(writeFn).deleteAllAsync(any());
    entries = new ArrayList<>();
    entries.add(new Entry<>("foo1", "bar111"));
    entries.add(new Entry<>("foo2", null));
    cachingTable.putAllAsync(entries).get();
    // Ensure cache is updated
    Assert.assertNull(guavaCache.getIfPresent("foo2"));
    // At this point, foo1 and foo3 should still exist
    Assert.assertNotNull(guavaCache.getIfPresent("foo1"));
    Assert.assertNotNull(guavaCache.getIfPresent("foo3"));
    // DELETE-ALL
    doReturn(CompletableFuture.completedFuture(null)).when(writeFn).deleteAllAsync(any());
    cachingTable.deleteAllAsync(Arrays.asList("foo1", "foo3")).get();
    // Ensure foo1 and foo3 are gone
    Assert.assertNull(guavaCache.getIfPresent("foo1"));
    Assert.assertNull(guavaCache.getIfPresent("foo3"));
}
Also used : HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ArrayList(java.util.ArrayList) Matchers.anyString(org.mockito.Matchers.anyString) RemoteTable(org.apache.samza.table.remote.RemoteTable) CompletableFuture(java.util.concurrent.CompletableFuture) Entry(org.apache.samza.storage.kv.Entry) GuavaCacheTable(org.apache.samza.table.caching.guava.GuavaCacheTable) Test(org.junit.Test)

Aggregations

GuavaCacheTable (org.apache.samza.table.caching.guava.GuavaCacheTable)3 RemoteTable (org.apache.samza.table.remote.RemoteTable)2 Test (org.junit.Test)2 Matchers.anyString (org.mockito.Matchers.anyString)2 CacheBuilder (com.google.common.cache.CacheBuilder)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Entry (org.apache.samza.storage.kv.Entry)1