Skip to content

关于版本2.5.2集群数据同步问题 #29

Description

@GoogleCodeExporter
在使用2.5.2的过程中,发现了一个设计上的问题(可能不一定
正确,望大家相互探讨)。
假设通过客户端使用两个memcached服务器实例A,B做集群,那么
客户端在第一次获取数据并放入服务器A的同时,也异步把相�
��的数据放入到服务器B,而如果在存入带有有效期的数据时��
�使用相对时间,假设有效期30分钟),那么相同的数据分别��
�放入A,B的失效时间点也将不同,因为是异步拷贝的,还不��
�证两台服务器的时钟总是一致的,假设这两种情况都会出现�
��那么存入服务器A,B的数据失效时间点差距就更大了,假设�
��5秒钟(即服务器A的数据失效5秒钟后,B的才达到失效时间��
�,而在这5秒钟之内,A是拿不到数据的了,结果客户端从B那�
��能拿到数据,可以看看这个类MemcachedCache的get方法都做了哪�
��事情:

public Object get(String key)
    {
        Object result = null;
        boolean isError = false;

        try
        {
            result = getCacheClient(key).get(key);  
        }
        catch(MemcachedException ex)
        {
            Logger.error(new StringBuilder(helper.getCacheName())
                .append(" cluster get error"),ex);

            isError = true;
        }


        if (result == null && helper.hasCluster())
            if (isError || helper.getClusterMode().equals
                    (MemcachedClientClusterConfig.CLUSTER_MODE_ACTIVE))
        {
            List<MemCachedClient> caches = helper.getClusterCache();

            for(MemCachedClient cache : caches)
            {
                if (getCacheClient(key).equals(cache))
                    continue;

                try
                {
                    try
                    {
                        result = cache.get(key);
                    }
                    catch(MemcachedException ex)
                    {
                        Logger.error(new StringBuilder(helper.getCacheName())
                            .append(" cluster get error"),ex);

                        continue;
                    }

                    //仅仅判断另一台备份机器,不多次判断,防止效率低下
                    if (helper.getClusterMode()
                            .equals(MemcachedClientClusterConfig.CLUSTER_MODE_ACTIVE) && result != null)
                    {
                        Object[] commands = new Object[]{CacheCommand.RECOVER,key,result};

                        addCommandToQueue(commands);
                    }

                    break;

                }
                catch(Exception e)
                {
                    Logger.error(new StringBuilder(helper.getCacheName())
                                .append(" cluster get error"),e);
                }

            }
        }


        return result;
    }


注意代码块:

//仅仅判断另一台备份机器,不多次判断,防止效率低下
if(helper.getClusterMode().equals(MemcachedClientClusterConfig.CLUSTER_MODE_ACTI
VE) && result != null)
    {
    Object[] commands = new Object[]{CacheCommand.RECOVER,key,result};

    addCommandToQueue(commands);
    }

这里的意思就是把从服务器B获取到的数据拷贝到服务器A,而
且是永久不过期的(命令数组中没有时间),而5秒钟过后,B
服务器中的数据将失效,重复前面所述的过程,把数据从服��
�器A拷贝到服务器B,同样变成永久不过期,最终的结果就是��
�置了有效期的数据,都有可能看起来永久无效一样杯具。

以上分析不知道是否存在,有点先斩后奏了,哥去验证一下��
�…

Original issue reported on code.google.com by dengq...@gmail.com on 24 Feb 2012 at 8:27

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions