Как сделать xmemcached быстрее
У меня есть проект, в котором мы пытаемся переложить основную часть кода PHP в Java-сервис. Одна из критических частей - транзакции memcached.
Я начал с xmemcached. Я использую двоичный протокол и пул соединений 5 для моего теста. У меня есть 10000 предметов в моем ведре два экземпляра memcached на самой машине. Я нажал на все 10000 элементов в php-memcached и в java, используя xmemcached.
В обеих сторонах я использую постоянные соединения. Получается одинаковое количество предметов. И PHP выполняет некоторую дополнительную обработку, пересекая массив значений по 10 КБ. Тем не менее, результатом является то, что php заканчивается через 0,9 до 1,2 секунд, а Java занимает от 1,6 до 2 секунд.
Эта большая задержка неприемлема для нашего проекта. Что еще можно сделать, чтобы ускорить xmemcached? Пожалуйста помоги
Вот код php:
$mem = new Memcached("p");
if(count($mem->getServerList()) <= 0) {
$mem->addServer("10.90.15.104",11211);
$mem->addServer("10.90.15.104",11311);
}
for($j=0; $j<1000; $j++) {
$startTime = microtime(true);
$memVals = array();
for($i=1; $i<=10000; $i++) {
$memVals[$i] = $mem->get($i);
}
$count=0;
foreach($memVals as $key=>$val) {
$val2 = $val;
if($val2 != '') {
$count++;
}
}
$endTime = microtime(true);
file_put_contents("/tmp/time.log",($endTime-$startTime)."\n",FILE_APPEND);
//echo "count>>$count\n";
//echo "time taken: ".($endTime-$startTime)."\n";
И вот код Java:
import AxMemcached.Adfeed;
import AxMemcached.AxMemcachedClientFactory;
import java.util.Calendar;
import net.rubyeye.xmemcached.MemcachedClient;
public class BigGet2 {
public static void main(String[] args) {
BigGet2 self = new BigGet2();
for (int j = 0; j < 1000; j++) {
Long timeStart = Calendar.getInstance().getTimeInMillis();
String value = "";
try {
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
net.rubyeye.xmemcached.utils.AddrUtil.getAddresses("10.90.15.104:11211 10.90.15.104:11311"));
builder.setConnectionPoolSize(10);
builder.setCommandFactory(new BinaryCommandFactory());
builder.setSessionLocator(new ArrayMemcachedSessionLocator(net.rubyeye.xmemcached.HashAlgorithm.ONE_AT_A_TIME));
MemcachedClient memcachedClient = builder.build();
for (int i = 1; i <= 10000; i++) {
value = memcachedClient.get(Integer.toString(i));
memcachedClient.get(Integer.toString(i));
}
Long timeEnd = Calendar.getInstance().getTimeInMillis();
Long timeTaken = timeEnd - timeStart;
System.out.println(timeTaken);
} catch (Exception e) {
}
}
}
}
1 ответ
Ниже приведен одноэлементный шаблон проектирования для создания memcached-соединения. Если ваш клиент приложения создает новое соединение для каждого запроса, вы увидите тонну потоков на соединение внутри JVM, которая будет занимать много памяти и, таким образом, вызывать чрезмерную сборку мусора, что замедлит работу вашего приложения.
@Singleton
public class MemcacheConnectionManager {
public MemcachedClient clientBuilder() throws IOException {
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
AddrUtil.getAddresses("localhost:11211"));
builder.setConnectionPoolSize(5);
MemcachedClient cacheClient = builder.build();
return cacheClient;
}
}
public class memcacheconsumer{
..
someCacheConsumerMethod(){
..
if(memcachedClient==null)
memcachedClient = memcacheConnection.clientBuilder();
...
}
}