| // Licensed to the Apache Software Foundation (ASF) under one or more |
| // contributor license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright ownership. |
| // The ASF licenses this file to You 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. |
| = Eviction Policies |
| |
| When link:persistence/native-persistence[Native Persistence] is off, Ignite holds all cache entries in the off-heap memory and allocates pages as new data comes in. |
| When a memory limit is reached and Ignite cannot allocate a page, some of the data must be purged from memory to avoid OutOfMemory errors. |
| This process is called _eviction_. Eviction prevents the system from running out of memory but at the cost of losing data and having to reload it when you need it again. |
| |
| Eviction is used in following cases: |
| |
| * for off-heap memory when link:persistence/native-persistence[Native Persistence] is off; |
| * for off-heap memory when Ignite is used with an link:persistence/external-storage[external storage]; |
| * for link:configuring-caches/on-heap-caching[on-heap caches]; |
| * for link:configuring-caches/near-cache[near caches] if configured. |
| |
| When Native Persistence is on, a similar process — called _page replacement_ — is used to free up off-heap memory when Ignite cannot allocate a new page. |
| The difference is that the data is not lost (because it is stored in the persistent storage), and therefore you are less concerned about losing data than about efficiency. |
| Page replacement is automatically handled by Ignite and is not user-configurable. |
| |
| == Off-Heap Memory Eviction |
| |
| Off-heap memory eviction is implemented as follows. |
| |
| When memory usage exceeds the preset limit, Ignite applies one of the preconfigured algorithms to select a memory page that is most suitable for eviction. |
| Then, each cache entry contained in the page is removed from the page. |
| However, if an entry is locked by a transaction, it is retained. |
| Thus, either the entire page or a large chunk of it is emptied and is ready to be reused. |
| |
| image::images/off_heap_memory_eviction.png[Off-Heap Memory Eviction Mechanism] |
| |
| By default, off-heap memory eviction is disabled, which means that the used memory constantly grows until it reaches its limit. |
| To enable eviction, specify the page eviction mode in the link:memory-configuration/data-regions/[data region configuration]. |
| Note that off-heap memory eviction is configured per link:memory-configuration/data-regions[data region]. |
| If you don't use data regions, you have to explicitly add default data region parameters in your configuration to be able to configure eviction. |
| |
| By default, eviction starts when the overall RAM consumption by a region gets to 90%. |
| Use the `DataRegionConfiguration.setEvictionThreshold(...)` parameter if you need to initiate eviction earlier or later. |
| |
| Ignite supports two page selection algorithms: |
| |
| * Random-LRU |
| * Random-2-LRU |
| |
| The differences between the two are explained below. |
| |
| === Random-LRU |
| |
| To enable the Random-LRU eviction algorithm, configure the data region as shown below: |
| |
| [tabs] |
| -- |
| tab:XML[] |
| [source,xml] |
| ---- |
| |
| include::code-snippets/xml/eviction.xml[tags=ignite-config;!discovery, indent=0] |
| |
| <bean class="org.apache.ignite.configuration.IgniteConfiguration"> |
| <!-- Memory configuration. --> |
| <property name="dataStorageConfiguration"> |
| <bean class="org.apache.ignite.configuration.DataStorageConfiguration"> |
| <property name="dataRegionConfigurations"> |
| <list> |
| <!-- |
| Defining a data region that consumes up to 20 GB of RAM. |
| --> |
| <bean class="org.apache.ignite.configuration.DataRegionConfiguration"> |
| <!-- Custom region name. --> |
| <property name="name" value="20GB_Region"/> |
| |
| <!-- 500 MB initial size (RAM). --> |
| <property name="initialSize" value="#{500L * 1024 * 1024}"/> |
| |
| <!-- 20 GB maximum size (RAM). --> |
| <property name="maxSize" value="#{20L * 1024 * 1024 * 1024}"/> |
| |
| <!-- Enabling RANDOM_LRU eviction for this region. --> |
| <property name="pageEvictionMode" value="RANDOM_LRU"/> |
| </bean> |
| </list> |
| </property> |
| </bean> |
| </property> |
| |
| <!-- The rest of the configuration. --> |
| </bean> |
| ---- |
| tab:Java[] |
| [source,java] |
| ---- |
| include::{javaCodeDir}/EvictionPolicies.java[tag=randomLRU,indent=0] |
| ---- |
| tab:C#/.NET[] |
| [source,csharp] |
| ---- |
| include::code-snippets/dotnet/EvictionPolicies.cs[tag=randomLRU,indent=0] |
| ---- |
| tab:C++[unsupported] |
| -- |
| |
| Random-LRU algorithm works as follows: |
| |
| * Once a memory region defined by a memory policy is configured, an off-heap array is allocated to track the 'last usage' timestamp for every individual data page. |
| * When a data page is accessed, its timestamp gets updated in the tracking array. |
| * When it is time to evict a page, the algorithm randomly chooses 5 indexes from the tracking array and evicts the page with the oldest timestamp. If some of the indexes point to non-data pages (index or system pages), then the algorithm picks another page. |
| |
| === Random-2-LRU |
| |
| To enable Random-2-LRU eviction algorithm, which is a scan-resistant version of Random-LRU, configure the data region, as shown in the example below: |
| |
| [tabs] |
| -- |
| tab:XML[] |
| [source,xml] |
| ---- |
| <bean class="org.apache.ignite.configuration.IgniteConfiguration"> |
| <!-- Memory configuration. --> |
| <property name="dataStorageConfiguration"> |
| <bean class="org.apache.ignite.configuration.DataStorageConfiguration"> |
| <property name="dataRegionConfigurations"> |
| <list> |
| <!-- |
| Defining a data region that consumes up to 20 GB of RAM. |
| --> |
| <bean class="org.apache.ignite.configuration.DataRegionConfiguration"> |
| <!-- Custom region name. --> |
| <property name="name" value="20GB_Region"/> |
| |
| <!-- 500 MB initial size (RAM). --> |
| <property name="initialSize" value="#{500L * 1024 * 1024}"/> |
| |
| <!-- 20 GB maximum size (RAM). --> |
| <property name="maxSize" value="#{20L * 1024 * 1024 * 1024}"/> |
| |
| <!-- Enabling RANDOM_2_LRU eviction for this region. --> |
| <property name="pageEvictionMode" value="RANDOM_2_LRU"/> |
| </bean> |
| </list> |
| </property> |
| </bean> |
| </property> |
| |
| <!-- The rest of the configuration. --> |
| </bean> |
| ---- |
| tab:Java[] |
| [source,java] |
| ---- |
| include::{javaCodeDir}/EvictionPolicies.java[tag=random2LRU,indent=0] |
| ---- |
| tab:C#/.NET[] |
| [source,csharp] |
| ---- |
| include::code-snippets/dotnet/EvictionPolicies.cs[tag=random2LRU,indent=0] |
| ---- |
| tab:C++[unsupported] |
| -- |
| |
| In Random-2-LRU, the two most recent access timestamps are stored for every data page. At the time of eviction, the algorithm randomly chooses 5 indexes from the tracking array and the minimum between two latest timestamps is taken for further comparison with corresponding minimums of four other pages that are chosen as eviction candidates. |
| |
| Random-LRU-2 outperforms LRU by resolving the "one-hit wonder" problem: if a data page is accessed rarely but accidentally accessed once, it's protected from eviction for a long time. |
| |
| == On-Heap Cache Eviction |
| |
| Refer to the link:configuring-caches/on-heap-caching#configuring-eviction-policy[Configuring Eviction Policy for On-Heap Caches] section for the instruction on how to configure eviction policy for on-heap caches. |