aurora-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zma...@apache.org
Subject aurora git commit: Implement custom MyBatis cache to record cache statistics.
Date Wed, 06 Apr 2016 23:10:28 GMT
Repository: aurora
Updated Branches:
  refs/heads/master 1a391d75f -> 9a93955a1


Implement custom MyBatis cache to record cache statistics.

This swaps out our use of the MyBatis default cache with a custom one backed by
Guava. The benefit of this is that we can now plumb cache statistics out which
is helpful in debugging performance problems with MyBatis.

Reviewed at https://reviews.apache.org/r/45821/


Project: http://git-wip-us.apache.org/repos/asf/aurora/repo
Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/9a93955a
Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/9a93955a
Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/9a93955a

Branch: refs/heads/master
Commit: 9a93955a159cd2e2c55002d9c3c75004e5654351
Parents: 1a391d7
Author: Zameer Manji <zmanji@apache.org>
Authored: Wed Apr 6 16:10:17 2016 -0700
Committer: Zameer Manji <zmanji@apache.org>
Committed: Wed Apr 6 16:10:17 2016 -0700

----------------------------------------------------------------------
 .../scheduler/storage/db/MyBatisCacheImpl.java  | 119 +++++++++++++++++++
 .../scheduler/storage/db/AttributeMapper.xml    |   4 +-
 .../scheduler/storage/db/TaskConfigMapper.xml   |   4 +-
 .../aurora/scheduler/storage/db/TaskMapper.xml  |   4 +-
 .../storage/db/MyBatisCacheImplTest.java        |  52 ++++++++
 5 files changed, 180 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aurora/blob/9a93955a/src/main/java/org/apache/aurora/scheduler/storage/db/MyBatisCacheImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/MyBatisCacheImpl.java b/src/main/java/org/apache/aurora/scheduler/storage/db/MyBatisCacheImpl.java
new file mode 100644
index 0000000..d9d406f
--- /dev/null
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/MyBatisCacheImpl.java
@@ -0,0 +1,119 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aurora.scheduler.storage.db;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReadWriteLock;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.primitives.Ints;
+
+import org.apache.aurora.common.stats.StatImpl;
+import org.apache.aurora.common.stats.Stats;
+import org.apache.ibatis.cache.Cache;
+
+import static java.util.Objects.requireNonNull;
+
+public class MyBatisCacheImpl implements Cache {
+  private com.google.common.cache.Cache<Object, Object> delegate;
+  private final String id;
+  private Integer size;
+  private final AtomicInteger clearCount = new AtomicInteger(0);
+
+  public MyBatisCacheImpl(String id) {
+    this.id = requireNonNull(id);
+  }
+
+  public void setSize(Integer size) {
+    this.size = requireNonNull(size);
+    initCache();
+  }
+
+  private void initCache() {
+    Preconditions.checkState(delegate == null);
+    requireNonNull(size);
+
+    delegate = CacheBuilder.newBuilder()
+        .maximumSize(size)
+        .recordStats()
+        .softValues()
+        .build();
+    initStats();
+  }
+
+  private void initStats() {
+    makeStat("request_count", () -> delegate.stats().requestCount());
+    makeStat("hit_count", () ->  delegate.stats().hitCount());
+    makeStat("hit_rate",  () -> delegate.stats().hitRate());
+    makeStat("miss_count", () -> delegate.stats().missCount());
+    makeStat("miss_rate", () -> delegate.stats().missRate());
+    makeStat("eviction_count", () -> delegate.stats().evictionCount());
+    makeStat("size", () -> delegate.size());
+    makeStat("clear_count", clearCount::get);
+  }
+
+  private <T extends Number> void makeStat(String name, Supplier<T> supplier)
{
+    String prefix = "db_storage_mybatis_cache_" + id + "_";
+    Stats.export(new StatImpl<Number>(prefix + name) {
+      @Override
+      public Number read() {
+        return supplier.get();
+      }
+    });
+  }
+
+  @Override
+  public String getId() {
+    return id;
+  }
+
+  @Override
+  public void putObject(Object key, Object value) {
+    if (key == null || value == null) {
+      return;
+    }
+    delegate.put(key, value);
+  }
+
+  @Override
+  public Object getObject(Object key) {
+    return delegate.getIfPresent(key);
+  }
+
+  @Override
+  public Object removeObject(Object key) {
+    delegate.invalidate(key);
+    // MyBatis says the return value is not used.
+    return null;
+  }
+
+  @Override
+  public void clear() {
+    delegate.invalidateAll();
+    clearCount.incrementAndGet();
+  }
+
+  @Override
+  public int getSize() {
+    return Ints.saturatedCast(delegate.size());
+  }
+
+  @Override
+  public ReadWriteLock getReadWriteLock() {
+    // MyBatis says this value is no longer used.
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/aurora/blob/9a93955a/src/main/resources/org/apache/aurora/scheduler/storage/db/AttributeMapper.xml
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/storage/db/AttributeMapper.xml
b/src/main/resources/org/apache/aurora/scheduler/storage/db/AttributeMapper.xml
index 41519de..91c76ca 100644
--- a/src/main/resources/org/apache/aurora/scheduler/storage/db/AttributeMapper.xml
+++ b/src/main/resources/org/apache/aurora/scheduler/storage/db/AttributeMapper.xml
@@ -3,7 +3,9 @@
     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="org.apache.aurora.scheduler.storage.db.AttributeMapper">
-  <cache size="50000" readOnly="true" />
+  <cache type="org.apache.aurora.scheduler.storage.db.MyBatisCacheImpl">
+    <property name="size" value="50000"/>
+  </cache>
   <insert id="insert">
     INSERT INTO host_attributes (
       host,

http://git-wip-us.apache.org/repos/asf/aurora/blob/9a93955a/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.xml
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.xml
b/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.xml
index fd272cc..5218967 100644
--- a/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.xml
+++ b/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.xml
@@ -17,7 +17,9 @@
     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="org.apache.aurora.scheduler.storage.db.TaskConfigMapper">
-  <cache size="1000" readOnly="true" />
+  <cache type="org.apache.aurora.scheduler.storage.db.MyBatisCacheImpl">
+    <property name="size" value="1000"/>
+  </cache>
   <insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="result.id">
     INSERT INTO task_configs (
       job_key_id,

http://git-wip-us.apache.org/repos/asf/aurora/blob/9a93955a/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskMapper.xml
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskMapper.xml b/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskMapper.xml
index 0219bf3..fb78a39 100644
--- a/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskMapper.xml
+++ b/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskMapper.xml
@@ -17,7 +17,9 @@
     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="org.apache.aurora.scheduler.storage.db.TaskMapper">
-  <cache size="10000" readOnly="true" />
+  <cache type="org.apache.aurora.scheduler.storage.db.MyBatisCacheImpl">
+    <property name="size" value="10000"/>
+  </cache>
   <insert id="insertScheduledTask" useGeneratedKeys="true" keyColumn="id" keyProperty="result.id">
     INSERT INTO tasks (
       task_id,

http://git-wip-us.apache.org/repos/asf/aurora/blob/9a93955a/src/test/java/org/apache/aurora/scheduler/storage/db/MyBatisCacheImplTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/storage/db/MyBatisCacheImplTest.java
b/src/test/java/org/apache/aurora/scheduler/storage/db/MyBatisCacheImplTest.java
new file mode 100644
index 0000000..1ed1a12
--- /dev/null
+++ b/src/test/java/org/apache/aurora/scheduler/storage/db/MyBatisCacheImplTest.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aurora.scheduler.storage.db;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class MyBatisCacheImplTest {
+  private MyBatisCacheImpl cache;
+
+  @Before
+  public void setUp() {
+    cache = new MyBatisCacheImpl("cache.id");
+  }
+
+  @Test(expected = NullPointerException.class)
+  public void testExceptionWithoutSize() {
+    cache.getSize();
+  }
+
+  @Test
+  public void testGetAndSet() {
+    String key = "key";
+    String value = "value";
+
+    cache.setSize(100);
+
+    assertNull(cache.getObject(key));
+
+    cache.putObject(key, value);
+
+    assertEquals(cache.getObject(key), value);
+
+    cache.clear();
+
+    assertNull(cache.getObject(key));
+  }
+}


Mime
View raw message