Cluster storage session storage, page storage, data storage

I am dealing with a custom implementation for the gateway session store, data store, page store. I have a cu cluster gate and make it work in the following situation:

There are 2 nodes in the cluster, node is one, and the user should be able to continue the flow without noticing pages with full state, with a large number of ajax requests. While I am storing the wicket session in user storage via rmi, and I am trying to expand DiskPageStore. The new call is the inner SessionEntry class, it is still supported by ConcurrentMap.

My question is: has anyone done this before? Do you have any suggestions on how to do this?

+4
source share
1 answer

My suggestion is to forget about DiskPageStore and SessionEntry in your situation. The parallel card you specified is stored locally on the heap. Once one of the nodes fails, it is not possible to access its ConcurrentMap, and the Wicket resources mentioned in ConcurrentMap will be unavailable.

Therefore, in a clustered environment, you need to group the Wicket page store. Versions of pages may be expired based on a specific policy or intentionally deleted when their respective session expires.

I have enabled the web session and data warehouse clustering for Apache Wicket, which is used in the enterprise web application in production, and it works very well. The software that I use:

  • JDK 1.8.0_60
  • Apache Tomcat 8.0.33 (Tomcat 7 )
  • Wicket 6.16 ( 6.22.0 7.2.0 )
  • Apache Ignite 1.7.0
  • : Crossroads
  • Ubuntu 14.04.1

Apache Ignite -, , -.

-, ( ) Ignite, - Wicket ( , ). Wicket page store, , .

Wicket HttpSessionDataStore, . . Apache Ignite . IDataStore, Ignite. ​​.

import java.util.concurrent.TimeUnit;
import javax.cache.expiry.Duration;
import javax.cache.expiry.TouchedExpiryPolicy;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CacheMemoryMode;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.eviction.lru.LruEvictionPolicy;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.wicket.pageStore.IDataStore;
import org.apache.wicket.pageStore.memory.IDataStoreEvictionStrategy;
import org.apache.wicket.pageStore.memory.PageTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class IgniteDataStore implements IDataStore {

    private static final Logger log = LoggerFactory.getLogger(IgniteDataStore.class);

    private final IDataStoreEvictionStrategy evictionStrategy;
    private Ignite ignite;
    IgniteCache<String, PageTable> igniteCache;

    public IgniteDataStore(IDataStoreEvictionStrategy evictionStrategy) {
        this.evictionStrategy = evictionStrategy;

        CacheConfiguration<String, PageTable> cacheCfg = new CacheConfiguration<String, PageTable>("wicket-data-store");
        cacheCfg.setCacheMode(CacheMode.PARTITIONED);
        cacheCfg.setBackups(1);

        cacheCfg.setMemoryMode(CacheMemoryMode.OFFHEAP_VALUES);
        cacheCfg.setOffHeapMaxMemory(2 * 1024L * 1024L * 1024L); // 2 Gigabytes.

        cacheCfg.setEvictionPolicy(new LruEvictionPolicy<String, PageTable>(10000));

        cacheCfg.setExpiryPolicyFactory(TouchedExpiryPolicy.factoryOf(new Duration(TimeUnit.SECONDS, 14400)));
        log.info("IgniteDataStore timeout is set to 14400 seconds.");

        ignite = Ignition.ignite();
        igniteCache = ignite.getOrCreateCache(cacheCfg);
    }

    @Override
    public synchronized byte[] getData(String sessionId, int id) {
        PageTable pageTable = getPageTable(sessionId, false);
        byte[] pageAsBytes = null;
        if (pageTable != null) {
            pageAsBytes = pageTable.getPage(id);
        }
        return pageAsBytes;
    }

    @Override
    public synchronized void removeData(String sessionId, int id) {
        PageTable pageTable = getPageTable(sessionId, false);
        if (pageTable != null) {
            pageTable.removePage(id);
        }
    }

    @Override
    public synchronized void removeData(String sessionId) {
        PageTable pageTable = getPageTable(sessionId, false);
        if (pageTable != null) {
            pageTable.clear();
        }
        igniteCache.remove(sessionId);
    }

    @Override
    public synchronized void storeData(String sessionId, int id, byte[] data) {
        PageTable pageTable = getPageTable(sessionId, true);
        if (pageTable != null) {
            pageTable.storePage(id, data);
            evictionStrategy.evict(pageTable);
            igniteCache.put(sessionId, pageTable);
        } else {
            log.error("Cannot store the data for page with id '{}' in session with id '{}'", id, sessionId);
        }
    }

    @Override
    public synchronized void destroy() {
        igniteCache.clear();
    }

    @Override
    public boolean isReplicated() {
        return true;
    }

    @Override
    public boolean canBeAsynchronous() {
        return false;
    }

    private PageTable getPageTable(String sessionId, boolean create) {  
        if (igniteCache.containsKey(sessionId)) {
            return igniteCache.get(sessionId);
        }

        if (!create) {
            return null;
        }

        PageTable pageTable = new PageTable();
        igniteCache.put(sessionId, pageTable);
        return pageTable;
    }
}

, .

+3

All Articles