Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Higher level cache above the standard RocksDB cache #935

jakubcech opened this issue Aug 13, 2018 · 2 comments


Copy link

commented Aug 13, 2018


Currently RocksDB caches data in bytes, this means that you may create two separate transaction objects and manipulate them in different threads.

We want to create a cache layer above the DB implementation that locks in X K transactions and only stored them to the actual DB when evicting. This should allow us to avoid most reads from the DB.


Reducing I/O overhead.


  • We store the transaction object in the cache.
  • Benchmark disabling the RocksDB block cache
  • Every time we save or read a transaction we store it in the cache. Not in the DB.
  • Only write to the disk when we evict from the cache.
  • Eviction policy: When the cache is full, we evict a block of X transactions. FIFO.
  • The cache will be Y transactions.
  • Purge the cache to the db on shutdown

Open Questions (optional)

We need to decide on the number of transactions that we want to store and calculate the amount of memory that would occupy for the node. Without any calculations, I'd like to be able to store an amount of transactions that supports 1000 TPS, but that is likely a ton of memory. We can start with 50-100 and see what that gets us. The eviction policy should be a fraction of the pool. For example 1%, 3%, 10%, ... whatever makes sense for the given size.

Configurability I'm open to unless we can squeeze a sufficient amount of TXs into a very small memory footprint (which I reckon we can't). In which case I'd recommend adding a minimum value to the configuration parameter, e.g., at least a transaction worth of 100-200 MB, which should at least somewhat help even low resource nodes.

I'm a bit reserved towards having the cache size dynamic. As we'd have to monitor/count the amount of inflow TXs and then react based on that, meaning that if a large jump in TPS happened, we'd have to evict a lot of transactions very fast before we adjust the cache mechanism. But happy if someone proves me wrong with an approach that would work here.


This comment has been minimized.

Copy link

commented Nov 4, 2018

The problems are:

  1. The data is replicated from the block cache to the java application layer, causing a waste of memory.
  2. If a transaction has been read from cache more than one time, several Transaction will be created consuming more memory.
  3. There can race conditions between the 2 objects created. Currently it is not too bad since "Solidity" and "Validity" can only be changed from false to true and not the other way around. Still we may perform needless calculations.

I offer that we create a new cache that will replace RocksDb block cache. It will be either based on Guava's cache or be a synchronized map of weak references like but with concurrent purging.

Everytime we store to the db we simply also write in cache.


This comment has been minimized.

Copy link

commented Jun 26, 2019

This is the cache Hans created to whoever is interested:

He said that the change failed on tests, and it was a problem fixing it which is why we didn't continue.

@kwek20 kwek20 self-assigned this Jul 2, 2019

@jakubcech jakubcech removed the L-Groom label Jul 9, 2019

@jakubcech jakubcech added this to the LaLa milestone Jul 9, 2019

@kwek20 kwek20 referenced this issue Jul 15, 2019
5 of 5 tasks complete

@jakubcech jakubcech modified the milestones: LaLa, Pingu Jul 22, 2019

@jakubcech jakubcech modified the milestones: Pingu, Umbreon Aug 5, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
3 participants
You can’t perform that action at this time.