You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2010/01/07 06:46:31 UTC

svn commit: r896755 - in /incubator/cassandra/trunk: conf/ src/java/org/apache/cassandra/config/ src/java/org/apache/cassandra/db/ test/conf/

Author: jbellis
Date: Thu Jan  7 05:46:30 2010
New Revision: 896755

URL: http://svn.apache.org/viewvc?rev=896755&view=rev
Log:
use throughput and op count instead of size and column count to determine when to flush, greatly reducing the amount of synchronization required to insert
patch by jbellis; tested by Brandon Williams for CASSANDRA-658

Modified:
    incubator/cassandra/trunk/conf/storage-conf.xml
    incubator/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamily.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/db/Memtable.java
    incubator/cassandra/trunk/test/conf/storage-conf.xml

Modified: incubator/cassandra/trunk/conf/storage-conf.xml
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/conf/storage-conf.xml?rev=896755&r1=896754&r2=896755&view=diff
==============================================================================
--- incubator/cassandra/trunk/conf/storage-conf.xml (original)
+++ incubator/cassandra/trunk/conf/storage-conf.xml Thu Jan  7 05:46:30 2010
@@ -267,19 +267,24 @@
   <ColumnIndexSizeInKB>64</ColumnIndexSizeInKB>
 
   <!--
-   ~ The maximum amount of data to store in memory per ColumnFamily before
-   ~ flushing to disk.  Note: There is one memtable per column family, and 
+   ~ Flush memtable after this much data has been inserted, including
+   ~ overwritten data.  There is one memtable per column family, and 
    ~ this threshold is based solely on the amount of data stored, not
    ~ actual heap memory usage (there is some overhead in indexing the
    ~ columns).
   -->
-  <MemtableSizeInMB>64</MemtableSizeInMB>
+  <MemtableThroughputInMB>64</MemtableThroughputInMB>
+  <!--
+   ~ Throughput setting for Binary Memtables.  Typically these are
+   ~ used for bulk load so you want them to be larger.
+  -->
+  <BinaryMemtableThroughputInMB>256</BinaryMemtableThroughputInMB>
   <!--
    ~ The maximum number of columns in millions to store in memory per
    ~ ColumnFamily before flushing to disk.  This is also a per-memtable
-   ~ setting.  Use with MemtableSizeInMB to tune memory usage.
+   ~ setting.  Use with MemtableThroughputInMB to tune memory usage.
   -->
-  <MemtableObjectCountInMillions>0.1</MemtableObjectCountInMillions>
+  <MemtableOperationsInMillions>0.1</MemtableOperationsInMillions>
   <!--
    ~ The maximum time to leave a dirty memtable unflushed.
    ~ (While any affected columnfamilies have unflushed data from a
@@ -338,11 +343,4 @@
    ~ ten days.
   -->
   <GCGraceSeconds>864000</GCGraceSeconds>
-
-  <!--
-   ~ The threshold size in megabytes the binary memtable must grow to,
-   ~ before it's submitted for flushing to disk.
-  -->
-  <BinaryMemtableSizeInMB>256</BinaryMemtableSizeInMB>
-
 </Storage>

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java?rev=896755&r1=896754&r2=896755&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java Thu Jan  7 05:46:30 2010
@@ -103,9 +103,9 @@
     /* Number of minutes to keep a memtable in memory */
     private static int memtableLifetimeMs_ = 60 * 60 * 1000;
     /* Size of the memtable in memory before it is dumped */
-    private static int memtableSize_ = 128;
+    private static int memtableThroughput_ = 128;
     /* Number of objects in millions in the memtable before it is dumped */
-    private static double memtableObjectCount_ = 1;
+    private static double memtableOperations_ = 1;
     /* 
      * This parameter enables or disables consistency checks. 
      * If set to false the read repairs are disable for very
@@ -301,7 +301,7 @@
                 slicedReadBufferSizeInKB_ = Integer.parseInt(rawSlicedBuffer);
             }
 
-            String bmtThreshold = xmlUtils.getNodeValue("/Storage/BinaryMemtableSizeInMB");
+            String bmtThreshold = xmlUtils.getNodeValue("/Storage/BinaryMemtableThroughputInMB");
             if (bmtThreshold != null)
             {
                 bmtThreshold_ = Integer.parseInt(bmtThreshold);
@@ -395,14 +395,14 @@
                 memtableLifetimeMs_ = Integer.parseInt(lifetime) * 60 * 1000;
 
             /* Size of the memtable in memory in MB before it is dumped */
-            String memtableSize = xmlUtils.getNodeValue("/Storage/MemtableSizeInMB");
+            String memtableSize = xmlUtils.getNodeValue("/Storage/MemtableThroughputInMB");
             if ( memtableSize != null )
-                memtableSize_ = Integer.parseInt(memtableSize);
+                memtableThroughput_ = Integer.parseInt(memtableSize);
             /* Number of objects in millions in the memtable before it is dumped */
-            String memtableObjectCount = xmlUtils.getNodeValue("/Storage/MemtableObjectCountInMillions");
+            String memtableObjectCount = xmlUtils.getNodeValue("/Storage/MemtableOperationsInMillions");
             if ( memtableObjectCount != null )
-                memtableObjectCount_ = Double.parseDouble(memtableObjectCount);
-            if (memtableObjectCount_ <= 0)
+                memtableOperations_ = Double.parseDouble(memtableObjectCount);
+            if (memtableOperations_ <= 0)
             {
                 throw new ConfigurationException("Memtable object count must be a positive double");
             }
@@ -728,14 +728,14 @@
       return initialToken_;
     }
 
-    public static int getMemtableSize()
+    public static int getMemtableThroughput()
     {
-      return memtableSize_;
+      return memtableThroughput_;
     }
 
-    public static double getMemtableObjectCount()
+    public static double getMemtableOperations()
     {
-      return memtableObjectCount_;
+      return memtableOperations_;
     }
 
     public static boolean getConsistencyCheck()

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamily.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamily.java?rev=896755&r1=896754&r2=896755&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamily.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamily.java Thu Jan  7 05:46:30 2010
@@ -80,7 +80,6 @@
     private transient ICompactSerializer2<IColumn> columnSerializer_;
     long markedForDeleteAt = Long.MIN_VALUE;
     int localDeletionTime = Integer.MIN_VALUE;
-    private AtomicInteger size_ = new AtomicInteger(0);
     private ConcurrentSkipListMap<byte[], IColumn> columns_;
 
     public ColumnFamily(String cfName, String columnType, AbstractType comparator, AbstractType subcolumnComparator)
@@ -182,7 +181,6 @@
     public void clear()
     {
     	columns_.clear();
-    	size_.set(0);
     }
 
     /*
@@ -199,20 +197,17 @@
             {
                 int oldSize = oldColumn.size();
                 ((SuperColumn) oldColumn).putColumn(column);
-                size_.addAndGet(oldColumn.size() - oldSize);
             }
             else
             {
                 if (((Column)oldColumn).comparePriority((Column)column) <= 0)
                 {
                     columns_.put(name, column);
-                    size_.addAndGet(column.size());
                 }
             }
         }
         else
         {
-            size_.addAndGet(column.size());
             columns_.put(name, column);
         }
     }
@@ -307,14 +302,12 @@
 
     int size()
     {
-        if (size_.get() == 0)
+        int size = 0;
+        for (IColumn column : columns_.values())
         {
-            for (IColumn column : columns_.values())
-            {
-                size_.addAndGet(column.size());
-            }
+            size += column.size();
         }
-        return size_.get();
+        return size;
     }
 
     public int hashCode()

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=896755&r1=896754&r2=896755&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java Thu Jan  7 05:46:30 2010
@@ -692,12 +692,12 @@
 
     public int getMemtableColumnsCount()
     {
-        return getMemtableThreadSafe().getCurrentObjectCount();
+        return getMemtableThreadSafe().getCurrentOperations();
     }
 
     public int getMemtableDataSize()
     {
-        return getMemtableThreadSafe().getCurrentSize();
+        return getMemtableThreadSafe().getCurrentThroughput();
     }
 
     public int getMemtableSwitchCount()

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/db/Memtable.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/Memtable.java?rev=896755&r1=896754&r2=896755&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/db/Memtable.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/db/Memtable.java Thu Jan  7 05:46:30 2010
@@ -44,11 +44,11 @@
     private boolean isFrozen_;
     private volatile boolean isFlushed_; // for tests, in particular forceBlockingFlush asserts this
 
-    private final int threshold_ = DatabaseDescriptor.getMemtableSize()*1024*1024; // not static since we might want to change at runtime
-    private final int thresholdCount_ = (int)(DatabaseDescriptor.getMemtableObjectCount()*1024*1024);
+    private final int threshold_ = DatabaseDescriptor.getMemtableThroughput()*1024*1024; // not static since we might want to change at runtime
+    private final int thresholdCount_ = (int)(DatabaseDescriptor.getMemtableOperations()*1024*1024);
 
-    private final AtomicInteger currentSize_ = new AtomicInteger(0);
-    private final AtomicInteger currentObjectCount_ = new AtomicInteger(0);
+    private final AtomicInteger currentThroughput_ = new AtomicInteger(0);
+    private final AtomicInteger currentOperations = new AtomicInteger(0);
 
     private final String table_;
     private final String cfName_;
@@ -92,29 +92,19 @@
     		return 0;
     }
 
-    public int getCurrentSize()
+    public int getCurrentThroughput()
     {
-        return currentSize_.get();
+        return currentThroughput_.get();
     }
     
-    public int getCurrentObjectCount()
+    public int getCurrentOperations()
     {
-        return currentObjectCount_.get();
-    }
-
-    void resolveSize(int oldSize, int newSize)
-    {
-        currentSize_.addAndGet(newSize - oldSize);
-    }
-
-    void resolveCount(int oldCount, int newCount)
-    {
-        currentObjectCount_.addAndGet(newCount - oldCount);
+        return currentOperations.get();
     }
 
     boolean isThresholdViolated()
     {
-        return currentSize_.get() >= threshold_ || currentObjectCount_.get() >= thresholdCount_;
+        return currentThroughput_.get() >= threshold_ || currentOperations.get() >= thresholdCount_;
     }
 
     String getColumnFamily()
@@ -143,29 +133,19 @@
         resolve(key, columnFamily);
     }
 
-    private void resolve(String key, ColumnFamily columnFamily)
+    private void resolve(String key, ColumnFamily cf)
     {
         DecoratedKey decoratedKey = partitioner_.decorateKey(key);
-        ColumnFamily oldCf = columnFamilies_.putIfAbsent(decoratedKey, columnFamily);
+        currentThroughput_.addAndGet(cf.size());
+        currentOperations.addAndGet(cf.getColumnCount());
+        ColumnFamily oldCf = columnFamilies_.putIfAbsent(decoratedKey, cf);
         if (oldCf == null)
-        {
-            currentSize_.addAndGet(columnFamily.size() + key.length());
-            currentObjectCount_.addAndGet(columnFamily.getColumnCount());
             return;
-        }
 
-        int oldSize, newSize;
-        int oldObjectCount, newObjectCount;
         synchronized (keyLocks[Math.abs(key.hashCode() % keyLocks.length)])
         {
-            oldSize = oldCf.size();
-            oldObjectCount = oldCf.getColumnCount();
-            oldCf.resolve(columnFamily);
-            newSize = oldCf.size();
-            newObjectCount = oldCf.getColumnCount();
+            oldCf.resolve(cf);
         }
-        resolveSize(oldSize, newSize);
-        resolveCount(oldObjectCount, newObjectCount);
     }
 
     // for debugging

Modified: incubator/cassandra/trunk/test/conf/storage-conf.xml
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/test/conf/storage-conf.xml?rev=896755&r1=896754&r2=896755&view=diff
==============================================================================
--- incubator/cassandra/trunk/test/conf/storage-conf.xml (original)
+++ incubator/cassandra/trunk/test/conf/storage-conf.xml Thu Jan  7 05:46:30 2010
@@ -40,8 +40,8 @@
    <BootstrapFileDirectory>build/test/cassandra/bootstrap</BootstrapFileDirectory>
    <DiskAccessMode>mmap</DiskAccessMode>
    <StagingFileDirectory>build/test/cassandra/staging</StagingFileDirectory>
-   <MemtableSizeInMB>1</MemtableSizeInMB>
-   <MemtableObjectCountInMillions>0.00002</MemtableObjectCountInMillions> <!-- 20 -->
+   <MemtableThroughputInMB>1</MemtableThroughputInMB>
+   <MemtableOperationsInMillions>0.00002</MemtableOperationsInMillions> <!-- 20 -->
    <Keyspaces>
      <Keyspace Name = "Keyspace1">
        <ColumnFamily Name="Standard1"/>