wjm901215的gravatar头像
wjm901215 2015-07-22 17:34:15

单个项目部署10台服务器,怎么保证数据缓存同步问题?

单个项目部署10台服务器,每台服务器部署2个节点,怎么保证数据缓存同步问题?
初步设想采用memcached,能说下memcached具体怎么部署吗?是部署在一台还是多台,如果多台怎么保证缓存数据同步?

所有回答列表(3)
最代码官方的gravatar头像
最代码官方  LV168 2015年7月22日

原则上尽量避免分布式事务,所以建议采取开源的cache技术来实现同步,比如redis等技术。

如果确实需要增加local cache和remote cache机制,则建议采用开源的cache同步技术来实现,比如jgroups,目前最代码已经增加了通过jgroups通知多台tomcat实例更新本地ehcache的机制。

jgroups-udp.xml

<config>
    <UDP mcast_addr="228.10.10.10" mcast_port="45588"
        mcast_send_buf_size="2097152" mcast_recv_buf_size="2097152"
        ucast_send_buf_size="4194304" ucast_recv_buf_size="2097152" bind_port="3233" />
    <PING timeout="2000" />
    <MERGE2 min_interval="5000" max_interval="10000" />
    <FD_SOCK />
    <VERIFY_SUSPECT timeout="1500" />
    <pbcast.NAKACK retransmit_timeout="2400,4800" />
    <UNICAST/>
    <FRAG />
    <pbcast.STABLE desired_avg_gossip="20000" />
    <pbcast.GMS join_timeout="5000" print_local_addr="true" />
    <pbcast.STATE_TRANSFER />
</config>

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- http://ehcache.org/ehcache.xml -->
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"
    monitoring="autodetect">

    <cacheManagerPeerProviderFactory
        class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
        properties="file=jgroups-udp.xml" />
    <diskStore path="/data/ehcache/cachetmpdir" />
    <defaultCache maxElementsInMemory="1000" eternal="true"
        overflowToDisk="false" memoryStoreEvictionPolicy="LRU" statistics="false" />

    <cache name="entity" maxElementsInMemory="1000" eternal="true"
        overflowToDisk="false" memoryStoreEvictionPolicy="LRU" statistics="false">
        <cacheEventListenerFactory
            class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
            properties="replicateAsynchronously=true, replicatePuts=true,
            replicateUpdates=true, replicateUpdatesViaCopy=false,
            replicateRemovals=true" />
    </cache>
</ehcache>  

比如findById这个方法增加了ehcahe的注解机制

    @Override
    @Caching(cacheable = { @Cacheable(value = "entity", key = "#root.target.key(#p0,#p1)", condition = "#root.target.condition(#p1)", unless = "#result == null") })
    public T findOneById(final long id, Class<T> clazz) {
        Specification<T> specification = new Specification<T>() {
            @Override
            public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,
                    CriteriaBuilder criteriaBuilder) {
                Predicate _id = criteriaBuilder.equal(root.get("id"), id);
                return criteriaBuilder.and(_id);
            }

        };
        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<T> cq = builder.createQuery(clazz);
        Root<T> root = cq.from(clazz);
        Predicate predicate = specification.toPredicate(root, cq, builder);
        cq.select(root).where(predicate);
        T t = null;
        try {
            t = em.createQuery(cq).getSingleResult();
        } catch (Exception e) {
            logger.error("###Fail to findOneById() id:" + id + " clazz:"
                    + clazz + " Exception:" + e.getMessage());
        }
        return t;
    }

参考资料:

spring整合ehcache的入门级别demo分享,通过junit来测试

spring整合hibernate+ehcache实现最简单的入门代码demo实例,对初学者很有帮助

ehcache相关代码demo

jgroups自带demo实现类似我画你猜的代码

评论(5) 最佳答案
DrSoul的gravatar头像
DrSoul  LV4 2015年7月23日

member cache本身支持集群,通过集群,设置了同步方式,那么你一个节点的更新将会通知其他节点更新,至于缓存更新的控制,完全是业务和代码层面的控制,如果你使用spring,那么直接使用cache注解,直接更新membercache中的数据,其他节点也会同时更新,延时很小

DataPudge的gravatar头像
DataPudge  LV3 2015年7月23日

使用zk技术

顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友