Hi,

Please properly subscribe to the mailing list so that the community can
receive email notifications for your messages. To subscribe, send empty
email to user-subscr...@ignite.apache.org and follow simple instructions in
the reply.



I've made a test and fifo eviction policy works fine for me on ignite 1.7,
1.8, 1.9 and master.
However, I found a bug that cache size can be wrong until first write
attempt to cache. I've create a ticket [1]

PFA repro.

[1] https://issues.apache.org/jira/browse/IGNITE-4881


You wrote:

We are configuring an ignite 1.7.0 setup with to server nodes and several
> client ones to use it as a temporary cache. We need that all the info is
> available even if one of the server nodes goes down so we choose to have
> our cache in REPLICATED mode. We also want that there are no more than n
> entries on our cache, so we have limited the size of it with a FIFO
> eviction policy.
> In out testing we configure an eviction policy with a max size of 15. Then
> run a simple loop that inserts 20 entries on the cache named from key0 to
> key19. After running the loop, conncting with ignitevisord and running
> cache -scan shows all 20 entries. Then we take down one server node. Get it
> up again. Let the cluster time to replicate the data and take down the
> other server node. Then a cache -scan returns 15 of the 20 initial entries
> selected at "random", but what we expected was to see the last 15: from
> key5 to key19. Because of the first five had been evicted and didn't
> survive the nodes restart.
> I suspect an error in either the configuration of the cache or in our
> understanding of the replication - eviction interaction. ¿ Can anyone
> enlight us on what is happening ?
> We are defining our cache statically on the server nodes xml config file
> like this:
>   <property name="cacheConfiguration">
>    <bean class="org.apache.ignite.configuration.CacheConfiguration">
>     <property name="name" value="TEST"/>
>     <property name="cacheMode" value="REPLICATED"/>
>     <property name="writeSynchronizationMode" value="PRIMARY_SYNC"/>
>     <property name="atomicityMode" value="ATOMIC"/>
>     <property name="rebalanceMode" value="ASYNC"/>
>     <!-- Expire data after 10 minutes -->
>     <property name="expiryPolicyFactory">
>      <bean id="expiryPolicy"
> class="javax.cache.expiry.CreatedExpiryPolicy" factory-method="factoryOf">
>       <constructor-arg>
>        <bean class="javax.cache.expiry.Duration">
>         <constructor-arg value="SECONDS"/>
>         <constructor-arg value="600"/>
>        </bean>
>       </constructor-arg>
>      </bean>
>     </property>
>     <!-- Eviction policy: keep only 15 elements -->
>     <property name="evictionPolicy">
>      <bean
> class="org.apache.ignite.cache.eviction.fifo.FifoEvictionPolicy">
>       <property name="maxSize" value="15"/>
>      </bean>
>     </property>
>     -<property name="offHeapMaxMemory" value="-1"/>
>     <property name="swapEnabled" value="false"/>
>    </bean>
>   </property>
> For populating the cache we are using a simple java class that connects to
> the cluster and inerts the values on the cache. We use NearCache in our
> client connection with an eviction policy of 10.
>

-- 

Best regards,
Andrey V. Mashenkov
package userlist.repro;

import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.CacheRebalanceMode;
import org.apache.ignite.cache.CacheWriteSynchronizationMode;
import org.apache.ignite.cache.eviction.fifo.FifoEvictionPolicy;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;

/**
 *
 */
public class EvictionPolicyTest extends GridCommonAbstractTest {
    /** */
    private static CacheConfiguration cacheConfig(String cacheName) {
        CacheConfiguration<String, String> ccfg = new CacheConfiguration<>(cacheName);
        ccfg.setCacheMode(CacheMode.REPLICATED);

        ccfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.PRIMARY_SYNC);

        ccfg.setRebalanceMode(CacheRebalanceMode.ASYNC);

        final FifoEvictionPolicy<String, String> policy = new FifoEvictionPolicy<>();

        policy.setMaxSize(15);

        ccfg.setEvictionPolicy(policy);

        return ccfg;
    }

    /** */
    public void testFifoEvictionPolicy() throws InterruptedException {
        try {
            final Ignite node0 = Ignition.start(new IgniteConfiguration().setGridName("node-0"));
            final Ignite node1 = Ignition.start(new IgniteConfiguration().setGridName("node-1"));

            IgniteCache<String, String> cache = node0.getOrCreateCache(cacheConfig("myCache"));

            for (int i = 0; i < 20; i++)
                cache.put("key" + i, "val" + i);

            assertEquals(15, cache.size());

            validateCache(cache);

            node1.close();

            awaitPartitionMapExchange(true, true, null);

// Next assert will fail due to wrong cache size is returned.
//            assertEquals(15, cache.size());

            validateCache(cache);

/*
    Next assert will fail as get operation won't make size correct even if rebalance mode would set to SYNC.
    But putIfAbsent will make size to become correct
 */
//            cache.putIfAbsent("key15","somevalue");
//            assertEquals(15, cache.size());
        }
        finally {
            Ignition.stopAll(true);
        }
    }

    /** */
    private void validateCache(IgniteCache<String, String> cache) {
        for (int i = 0; i < 5; i++)
            assertNull(cache.get("key" + i));

        for (int i = 5; i < 20; i++) {
            final String val = cache.get("key" + i);

            assertNotNull(val);

            assertEquals("val" + i, val);
        }
    }
}

Reply via email to