srz / RedisClient4Java

4 stars 2 forks source link

连接数超过256会有警告 #1

Closed sumerone closed 12 years ago

sumerone commented 13 years ago

警告: You are creating too many HashedWheelTimer instances. HashedWheelTimer is a shared resource that must be reused across the application, so that only a few instances are created.

srz commented 13 years ago

你好,抱歉刚刚看到你的消息。 HashedWheelTimer 是我在项目中使用的一个定时器,在一个多线程环境下,一般只需要创建一个RedisClient实例即可,而一个实例只会使用一个Timer,你说连接数超过256会有警告,是不是你在每个线程都会new一个RedisClient实例呢?如果是这样的请修改为所有线程只访问同一个RedisClient实例即可,在RedisClient内部会做线程的同步工作,RedisClient是线程安全的。

sumerone commented 13 years ago

对的,我当时在做各个客户端的压力测试,看看在不同数量客户端并发的情况下的性能

在 2011-10-13,下午1:01, srz 写道:

你好,抱歉刚刚看到你的消息。 HashedWheelTimer 是我在项目中使用的一个定时器,在一个多线程环境下,一般只需要创建一个RedisClient实例即可,而一个实例只会使用一个Timer,你说连接数超过256会有警告,是不是你在每个线程都会new一个RedisClient实例呢?如果是这样的请修改为所有线程只访问同一个RedisClient实例即可,在RedisClient内部会做线程的同步工作,RedisClient是线程安全的。

Reply to this email directly or view it on GitHub: https://github.com/srz/RedisClient4Java/issues/1#issuecomment-2391302

宋仲凯 网易前台技术中心基础平台 CellPhone: 1375819550 Email: songzhongkai@gmail.com

sumerone commented 12 years ago

你的客户端支持sharding吗? serverList = new HashSet();

Sharding sharding = new Sharding(); sharding.setServerAddress(new InetSocketAddress(HOST, PORT)); serverList.add(sharding);

sharding = new Sharding(); sharding.setServerAddress(new InetSocketAddress(HOST, 63791)); serverList.add(sharding);

client = new RedisCacheClient(serverList);

这样创建客户端以后,好像没有把key hash到不同的实例去啊

srz commented 12 years ago

支持sharding,用的算法是一致性哈希,使用方法可以参考 org.elk.redis4j.test.Helper 类 中的 getRedisCacheClient() 方法 如 RedisClientBuilder builder = new RedisClientBuilder(); builder.addSharding(ip, port, 1, password); builder.addSharding(ip, port, 2, password); return builder.buildCacheClient();

至于你上面说的压力测试遇到的问题,我争取尽快把我之前做的测试代码也放上来供你参考吧,本来早就想放上来的,由于别的事耽误了。

sumerone commented 12 years ago

package org.netease.redis.redis4j.demo;

import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.HashSet; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong;

import org.elk.redis4j.api.Sharding; import org.elk.redis4j.impl.RedisClientBuilder; import org.elk.redis4j.impl.cache.RedisCacheClient;

public class Redis4jStringSetPerformance {

public static final int THREAD_COUNT = 1;

public static final int LOOP = 10000;

public static final int VALUE_SIZE = 100000;

public static final String HOST = "127.0.0.1";

public static final int PORT = 6379;

public static final String VALUE = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";

private static AtomicLong key = new AtomicLong(0);

private long start;

private Set<Sharding> serverList;

private RedisCacheClient client;

public Redis4jStringSetPerformance() throws UnknownHostException {

    serverList = new HashSet<Sharding>();

    Sharding sharding = new Sharding();
    sharding.setServerAddress(new InetSocketAddress(HOST, PORT));
    sharding.setUseHeartbeat(false);
    serverList.add(sharding);

    sharding = new Sharding();
    sharding.setServerAddress(new InetSocketAddress(HOST, 63791));
    sharding.setUseHeartbeat(false);
    serverList.add(sharding);

    client = new RedisCacheClient(serverList);

}

public void stringSetTest() {

    ExecutorService executor = Executors
            .newFixedThreadPool(THREAD_COUNT + 1);

    CountDownLatch latch = new CountDownLatch(THREAD_COUNT);

    System.err.println("Start set...");

    start = System.currentTimeMillis();

    for (int i = 0; i < THREAD_COUNT; i++) {
        SetRunable runable = new SetRunable(latch);
        executor.execute(runable);
    }

    executor.execute(new TimeCount(latch, "Set"));

    executor.shutdown();

}

public static void main(String[] args) throws UnknownHostException {

    (new Redis4jStringSetPerformance()).stringSetTest();

}

class SetRunable implements Runnable {

    private CountDownLatch downLatch;

    public SetRunable(CountDownLatch downLatch) {
        this.downLatch = downLatch;
    }

    @Override
    public void run() {

        for (int i = 0; i < LOOP; i++) {
            client.set(key.incrementAndGet() + "", VALUE);
        }

        this.downLatch.countDown();

    }
}

class TimeCount implements Runnable {

    private CountDownLatch downLatch;
    private String op;

    public TimeCount(CountDownLatch downLatch, String op) {
        this.downLatch = downLatch;
        this.op = op;
    }

    @Override
    public void run() {

        try {
            this.downLatch.await();
        } catch (InterruptedException e) {

            e.printStackTrace();
        }

        System.err.println(op + " complete, Use time:"
                + (System.currentTimeMillis() - start));

        client.quit();

    }
}

}

上面是我测试的代码,不知道我有没有写错?

在 2011-10-18,下午2:10, srz 写道:

支持sharding,用的算法是一致性哈希,使用方法可以参考 org.elk.redis4j.test.Helper 类 中的 getRedisCacheClient() 方法 如 RedisClientBuilder builder = new RedisClientBuilder(); builder.addSharding(ip, port, 1, password); builder.addSharding(ip, port, 2, password); return builder.buildCacheClient();

至于你上面说的压力测试遇到的问题,我争取尽快把我之前做的测试代码也放上来供你参考吧,本来早就想放上来的,由于别的事耽误了。

Reply to this email directly or view it on GitHub: https://github.com/srz/RedisClient4Java/issues/1#issuecomment-2438368

宋仲凯 网易前台技术中心基础平台 CellPhone: 1375819550 Email: songzhongkai@gmail.com

srz commented 12 years ago

你的代码在初始化client时有问题,我修改了构造函数部分,测试通过,我修改的内容是向index分别为1 和2的两个库里插入数据,最终在1的库里的数据有5088条,2的库里的数据有4912条,代码如下

package org.elk.redis4j.test;

import java.net.UnknownHostException; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong;

import org.elk.redis4j.api.Sharding; import org.elk.redis4j.api.cache.IRedisCacheClient; import org.elk.redis4j.impl.RedisClientBuilder;

public class Redis4jStringSetPerformance {

public static final int THREAD_COUNT = 1;

public static final int LOOP = 10000;

public static final int VALUE_SIZE = 100000;

public static final String HOST = "172.19.32.46";

public static final int PORT = 6379;

public static final String VALUE = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";

private static AtomicLong key = new AtomicLong(0);

private long start;

private Set<Sharding> serverList;

private IRedisCacheClient client;

public Redis4jStringSetPerformance() throws UnknownHostException
{

// serverList = new HashSet(); // // Sharding sharding = new Sharding(); // sharding.setServerAddress(new InetSocketAddress(HOST, PORT)); // sharding.setUseHeartbeat(false); // serverList.add(sharding); // // sharding = new Sharding(); // sharding.setServerAddress(new InetSocketAddress(HOST, PORT)); // sharding.setUseHeartbeat(false); // serverList.add(sharding); // // client = new RedisCacheClient(serverList);

    RedisClientBuilder builder = new RedisClientBuilder();
    builder.addSharding(HOST, PORT, 1, "");
    builder.addSharding(HOST, PORT, 2, "");
    client = builder.buildCacheClient();

}

public void stringSetTest()
{

    ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT + 1);

    CountDownLatch latch = new CountDownLatch(THREAD_COUNT);

    System.err.println("Start set...");

    start = System.currentTimeMillis();

    for (int i = 0; i < THREAD_COUNT; i++)
    {
        SetRunable runable = new SetRunable(latch);
        executor.execute(runable);
    }

    executor.execute(new TimeCount(latch, "Set"));

    executor.shutdown();

}

public static void main(String[] args) throws UnknownHostException
{

    (new Redis4jStringSetPerformance()).stringSetTest();

}

class SetRunable implements Runnable
{

    private CountDownLatch downLatch;

    public SetRunable(CountDownLatch downLatch)
    {
        this.downLatch = downLatch;
    }

    @Override
    public void run()
    {

        for (int i = 0; i < LOOP; i++)
        {
            client.set(key.incrementAndGet() + "", VALUE);
        }

        this.downLatch.countDown();

    }
}

class TimeCount implements Runnable
{

    private CountDownLatch downLatch;
    private String op;

    public TimeCount(CountDownLatch downLatch, String op)
    {
        this.downLatch = downLatch;
        this.op = op;
    }

    @Override
    public void run()
    {

        try
        {
            this.downLatch.await();
        } catch (InterruptedException e)
        {

            e.printStackTrace();
        }

        System.err.println(op + " complete, Use time:" + (System.currentTimeMillis() - start));

        client.quit();

    }
}

}