Does ehcache reserve (allocate) heap memory set with maxBytesLocalHeap? - memory-management

I am using ehache v. 2.8.
But I am not sure if I understand the documentation correctly regarding reservation of the memory for the cache.
If the memory is set in ehcache.xml like this:
<ehcache maxBytesLocalHeap="256M">
(...)
</ehcache>
..will it actually be allocated at start and this cache will use exactly 256MB of heap or does this only mean (like it should, if this attribute is named like it is) that this cache can take at most 256MB of heap?

This means that this cache will do its best to contain 256MB or less of user data.
But note that the actual memory footprint of the cache can be somewhat larger due to internal data structures.
Also in case the cache operates at full capacity, it may temporarily go over size while eviction takes place.

Related

EhCache to put new element to disk if memory store full

I would like to use EhCache in combination of memory and disk cache. EhCache should move new elements to disk when memory is full. e.g. I have 100 elements in ehCache memory store and tries to put 101st element and if memory is full then put 101st element to disk not 1st element.
Could you please let me know the cache configuration to achieve this?
Ehcache no longer works that way. The tiering model introduced in Ehcache 2.6 and used since then will always store ALL mappings into the lower tier, disk in your case.
The reason is predictable latency. If Ehcache waited for the memory tier to be full before using the disk, you would see a latency increase maybe at the worst time for your application. While the model were all mappings are written to disk gives you the upper bound for the write latency, while reads may be faster for hot value that are available in memory directly.

EHcache performance in using disk store cache

We are using the ehcache in our application. Look at the following configuration:
<diskStore path="java.io.tmpdir" />
<cache name="service" maxElementsInMemory="50000" eternal="true" overflowToDisk="true"/>
Since we have configured as eternal="true", Is it going to create caches for ever?. Is there a chance of running out of disk space?
What would be the performance impact on disk store?. It is definitely slower than the in-memory cache, but how much impact.
If more caches are stored in the disk, will it cause IO issue of doing multiple file operations?
Please suggest the best practice for a production grade applications. Consider that we have a 3 GB heap memory and 25000 concurrent users accessing the application. But, there is no database used in our application.
The application is deployed in WAS 8.5.5.
eternal=true means mappings will never expire.
overflowToDisk=true means that all mappings put in the cache will end up written on disk, from the first mapping put in the cache. The current Ehcache tiering model (since version 2.6.0) always makes use of the slower store - disk here - in order to give you predictable latency. When a mapping is accessed, it gets faulted into heap for faster retrieval. When too many mappings are faulted in heap, eviction from heap kicks in to keep the heap cache size according to maxElementsInMemory.
Given that you do not size the disk store by setting maxElementsLocalDisk, it defaults to 0 which means no limit. So yes, you may run out of disk space if you never explicitly remove cache entries.
It is quite hard to recommend proper cache size without knowing the details of your application. What I can recommend is that you measure both heap and disk usage and assess when the increased memory usage outweighs the performance gain.

Does larger cache size always lead to improved performance?

Since cache inside the processor increases the instruction execution speed. I'm wondering what if we increase the size of cache to many MBs like 1 GB. Is it possible? If it is will increasing the cache size always result in increased performance?
There is a tradeoff between cache size and hit rate on one side and read latency with power consumption on another. So the answer to your first question is: technically (probably) possible, but unlikely to make sense, since L3 cache in modern CPUs with size of just a few MBs has read latency of about dozens of cycles.
Performance depends more on memory access pattern than on cache size. More precisely, if the program is mainly sequential, cache size is not a big deal. If there are quite a lot of random access (ex. when associative containers are actively used), cache size really matters.
The above is true for single computational tasks. In multiprocess environment with several active processes bigger cache size is always better, because of decrease of interprocess contention.
This is a simplification, but, one of the primary reasons the cache increases 'speed' is that it provides a fast memory very close to the processor - this is much faster to access than main memory. So, in theory, increasing the size of the cache should allow more information to be stored in this 'fast' memory, and thereby improve performance.. In the real world things are obviously much more complex than this, and there will of course be added complexity, and cost, associated with such a large cache, and with dealing with issues like cache coherency, caching algorithms etc.
As cache stores data temporary. Cache is used to locate the file easily that has been frequently using. So if the size of cache increased upto 1gb or more it will not stay as cache, it becomes RAM. Data is stored in ram temporary. So if cache isn't used, when data is called by processor, ram will take time to fetch data to provide to the processor because of its wide size of 4gb or more. So we use cache as our temporary memory for the things we recently or frequently used. In this way, ram ram doesnt required to find and fetch data to give it to processor, because processor direct access data from cache, because of small size of cache, it doesnt take time to find data, and processor doesn't require to call ram to fetch data, all of this done fastly without ram. Lets take an example, we have a wide classroom (RAM) , our principal (processor) call class CR (Data) for some purposes, then ones will go to the class room and will find the CR in the class of 1000 students and take him to the principal. It takes time. When we specify a space(cache) for CR in the class, because principal mostly call CR of the class, so it will become easy to find CR becuase most of the time CR is called by Principal.

why does the redis memory usage not reduce when del half of keys

Redis is used to save data but it costs a lot of memory, and its memory usage up to 52.5%.
I deleted half of the keys in redis, and the return code of the delete operation is ok, but its memory usage doesn't reduce.
What's the reason? Thanks in Advance.
My operation code is as below:
// save data
m_pReply = (redisReply *)redisCommand(m_pCntxt, "set %b %b", mykey.data(), mykey.size(), &myval, sizeof(myval));
// del data
m_pReply = (redisReply *)redisCommand(m_pCntxt, "del %b", mykey.data(), mykey.size());
The redis info:
redis 127.0.0.1:6979> info
redis_version:2.4.8
redis_git_sha1:00000000
redis_git_dirty:0
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.6
process_id:28799
uptime_in_seconds:1289592
uptime_in_days:14
lru_clock:127925
used_cpu_sys:148455.30
used_cpu_user:38023.92
used_cpu_sys_children:23187.60
used_cpu_user_children:123989.72
connected_clients:22
connected_slaves:0
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
used_memory:31903334872
used_memory_human:29.71G
used_memory_rss:34414981120
used_memory_peak:34015653264
used_memory_peak_human:31.68G
mem_fragmentation_ratio:1.08
mem_allocator:jemalloc-2.2.5
loading:0
aof_enabled:0
changes_since_last_save:177467
bgsave_in_progress:0
last_save_time:1343456339
bgrewriteaof_in_progress:0
total_connections_received:820
total_commands_processed:2412759064
expired_keys:0
evicted_keys:0
keyspace_hits:994257907
keyspace_misses:32760132
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:11672476
vm_enabled:0
role:slave
master_host:192.168.252.103
master_port:6479
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
db0:keys=66372158,expires=0
Please refer to Memory allocation section on the following link:
http://redis.io/topics/memory-optimization
I quoted it here:
Redis will not always free up (return) memory to the OS when keys are
removed. This is not something special about Redis, but it is how most
malloc() implementations work. For example if you fill an instance
with 5GB worth of data, and then remove the equivalent of 2GB of data,
the Resident Set Size (also known as the RSS, which is the number of
memory pages consumed by the process) will probably still be around
5GB, even if Redis will claim that the user memory is around 3GB. This
happens because the underlying allocator can't easily release the
memory. For example often most of the removed keys were allocated in
the same pages as the other keys that still exist.
Since Redis 4.0.0 there's a command for this:
MEMORY PURGE
Should do the trick: https://redis.io/commands/memory-purge
Note however that command docs state:
This command is currently implemented only when using jemalloc as an allocator, and evaluates to a benign NOOP for all others.
And the README reminds us that:
Redis is compiled and linked against libc
malloc by default, with the exception of jemalloc being the default on Linux
systems. This default was picked because jemalloc has proven to have fewer
fragmentation problems than libc malloc.
A good starting point is to use the Redis CLI command: MEMORY DOCTOR.
It can give you very valuable information and point you to the potential issue.
some useful links:
MEMORY DOCTOR command docs
What is defragmentation and what are the Redis defragmentation configs
example:
Peak memory: In the past this instance used more than 150% the memory that is currently using. The allocator is normally not able to release memory after a peak, so you can expect to see a big fragmentation ratio, however this is actually harmless and is only due to the memory peak, and if the Redis instance Resident Set Size (RSS) is currently bigger than expected, the memory will be used as soon as you fill the Redis instance with more data. If the memory peak was only occasional and you want to try to reclaim memory, please try the MEMORY PURGE command, otherwise the only other option is to shutdown and restart the instance.
High total RSS: This instance has a memory fragmentation and RSS overhead greater than 1.4 (this means that the Resident Set Size of the Redis process is much larger than the sum of the logical allocations Redis performed). This problem is usually due either to a large peak memory (check if there is a peak memory entry above in the report) or may result from a workload that causes the allocator to fragment memory a lot. If the problem is a large peak memory, then there is no issue. Otherwise, make sure you are using the Jemalloc allocator and not the default libc malloc. Note: The currently used allocator is "jemalloc-5.1.0".
High allocator fragmentation: This instance has an allocator external fragmentation greater than 1.1. This problem is usually due either to a large peak memory (check if there is a peak memory entry above in the report) or may result from a workload that causes the allocator to fragment memory a lot. You can try enabling 'activedefrag' config option.

When overFlowToDisk gets activated in EHCACHE?

I have some questions on "overflowToDisk" attribute of element?
1) I read at this URL that :
overflowToDisk sets whether element can overflow to disk when the memory store has reached the maximum limit.
"Memory" above refers JVM memory allocated for Java process running EHCACHE, or is there any parameter in to specify Cache memory size?
2) When the poces running EHCACHE terminates for some reason, whether this disk gets cleared and everything in cache gets vanished?
Elements start to overflow to the disk when you have more than maxElementsInMemory of them in the memory store. The following example creates a cache that stores 1000 elements in memory, and, if you need to store more, up to 10000 on disk:
<cache name="cacheName"
maxElementsInMemory="1000"
maxElementsOnDisk="10000"
overflowToDisk="true"
timeToIdleSeconds="..."
timeToLiveSeconds="...">
</cache>
For the second question, have a look at the diskPersistent parameter. If it is set to true, Ehcache will keep your data stored on the disk when you stop the JVM. The following example demonstrates this:
<cache name="cacheName"
maxElementsInMemory="1000"
maxElementsOnDisk="10000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="..."
timeToLiveSeconds="...">
</cache>
As of Ehcache 2.6, the storage model is no longer an overflow one but a tiered one. In the tiered storage model, all data will always be present in the lowest tier. Items will be present in the higher tiers based on their hotness.
Possible tiers for open source Ehcache are:
On-heap that is on the JVM heap
On-disk which is the lowest one
By definition high tiers have lower latency but less capacity than lower tiers.
So for an open source cache configured with overflowToDisk, all the data will always be inside the disk tier. It will store the key in memory and the data on disk.
Answer copied from this other question.

Resources