如何分片集?

时间:2018-12-25 23:24:29

标签: java spring-boot cloud scalability sharding

你能帮我一件事情吗?想象一下,我有一个具有一个GET方法的简单RESTful微服务器,该方法仅响应一个随机的String

我将所有字符串组装在ConcurrentHashSet<String>中,该字符串包含所有答案。

下面有一个草率的实现,主要是Set<String>是一个故障安全的,可以同时修改。

@RestController
public class Controller {

    private final StringService stringService;

    private final CacheService cacheService;

    public Controller(final StringService stringService, final CacheService cacheService) {
        this.stringService = stringService;
        this.cacheService = cacheService;
    }

    @GetMapping
    public String get() {
        final String str = stringService.random();
        cacheService.add(str);
        return str;
    }

}


public class CacheService {

    private final Set<String> set = ConcurrentHashMap.newKeySet();

    public void add(final String str) {
        set.add(str);
    }

}

当您阅读此专栏时,我的资料被10亿人使用。 我想分片缓存。由于我的系统负载很重,因此我无法将所有字符串保存在一台服务器上。我想拥有256个服务器/实例,并利用str.hashCode()%256函数来统一分配我的缓存,以确定在每个服务器/实例上是否应保留字符串。

您能告诉我下一步该怎么做吗? 假设目前,我只在本地运行Spring Boot应用程序。

3 个答案:

答案 0 :(得分:1)

您应该签出Hazelcast,它是开源的,并且在我想在应用程序的多个实例之间共享数据的情况下对我来说非常有用。 hazelcast提供的内存中数据网格可能只是您要寻找的东西。

答案 1 :(得分:1)

我同意Vicky,这就是Hazelcast的目的。它是一个jar,包含几行代码,而不是HashMap,而是一个IMap,它是HashMap的扩展,很方便。所有的分发,分片,并发等都为您完成。检出:

https://docs.hazelcast.org/docs/3.11.1/manual/html-single/index.html#map

答案 2 :(得分:0)

尝试遵循代码。但是,这是一种不好的方法,最好使用Map在一个实例中缓存数据。如果需要创建分布式应用程序,请尝试使用Redis之类的分布式catche服务。

class CacheService {

        /**
         * assume read operation is more frequently than write operation
         */
        private final static List<Set<String>> sets = new CopyOnWriteArrayList<>();

        static {
            for (int i = 0; i < 256; i++) {
                sets.add(ConcurrentHashMap.newKeySet());
            }
        }

        public void add(final String str) {
            int insertIndex = str.hashCode() % 256;
            sets.get(insertIndex).add(str);
        }

    }