LINUX.ORG.RU
ФорумAdmin

socket vs host:port - разница в более чем полтора раза?

 ,


1

2

Ковыряю Redis. Решил поиграться с конфигом и посмотреть, как там с разницей между подключением через юникс-сокет и хост:порт. Собственно такой вот простой бенчмарк, взято вроде как со швабры или откуда там:

<?php

try {
    $redis = new Redis();
    $redis->connect('localhost:6379');    
} catch(RedisException $e) {
    exit('Connect error');
}

$benchmark = microtime(true);

for($i=0;$i < 100000; $i++)
    $redis->set('key','value');

echo microtime(true) - $benchmark;

?>

На своей виртулалке с 1 ядром 2,4 ГГц и 512М рамы получил результаты порядка 4,0-4,5 с (в среднем 4,2 с). Поменяв

$redis->connect('localhost:6379');

на

$redis->connect('/var/run/redis/redis.sock');

получил ~2.5 с. Вот такая ***ня малята, использование сокета более чем в полтора раза повышает производительность. Сразу полез в документацию по мускулю - он естественно тоже умеет сокет (а везде пишут хост:порт - оно то правильно, потому что база может находится не только на локальном хосте), но почему-то НИГДЕ не пишут, что если все находится локально, то лучше использовать сокет. Щас думаю погуглить бенчмарки для mysql и сравнить результаты там.

★★★★★

Последнее исправление: leg0las (всего исправлений: 1)

А если виртуалку перед тестом перезагружать? Может какие-то эффекты от кешей. Хотя конечно при записи в память кешировать особо нечего, разве-что какие-то потроха редиса доподгружать с диска.

Мускулёвые клиенты используют юникс-сокет если указать в качестве хоста localhost (и игнорируют порт). Такие дела. Что-бы подключиться через loopback нужно указывать в качестве хоста 127.0.0.1

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

Ребут хоста дела не даст и собственно не дал - при хост:порт 4,0-4,1 с, при сокете 2,5-2,6 с. Про подключение к мускулю подобным способом не знал, я считаю что его (способ подключения) лучше указывать явно.

leg0las ★★★★★
() автор топика
Последнее исправление: leg0las (всего исправлений: 1)

Для мускуля кстати можно использовать такую конструкцию:

$socket = ini_get('mysql.default_socket');

или

$socket = ini_get('pdo_mysql.default_socket');

и затем (в моем случае с pdo):

$db = new PDO("mysql:unix_socket=$socket;dbname=$dbname", $user, $password, array(
    PDO::ATTR_PERSISTENT => true
    ));
leg0las ★★★★★
() автор топика
Ответ на: комментарий от leg0las

Мускуль считает что localhost это явное указание на «используй заданный в конфиге юникс-сокет» (:

Кстати на каком ядре ты тестировал?

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

Понял, принято к сведению. Тестил на дебиановском родном 3.2. php5-redis собирал из тестинга, да.

leg0las ★★★★★
() автор топика

Вот такая ***ня малята, использование сокета более чем в полтора раза повышает производительность. Сразу полез в документацию по мускулю - он естественно тоже умеет сокет (а везде пишут хост:порт - оно то правильно, потому что база может находится не только на локальном хосте), но почему-то НИГДЕ не пишут, что если все находится локально, то лучше использовать сокет.

Мне кажется, что все дело в том, что вантузятники не знают никаких этих ваших UNIX-сокетов.

anonymous
()

Есть такое дело. Я когда-то memcached тестировал подобным образом, разница в 3-4 раза была.

YAR ★★★★★
()
Ответ на: комментарий от YAR

Ого. Надо будет потыркаться вечерком.
Давеча впилил его в один сайтик, но поленился курить маны и решил что он только по сети умеет.

MrClon ★★★★★
()
Последнее исправление: MrClon (всего исправлений: 1)
Ответ на: комментарий от MrClon

А, нет, сорри, соврал, то что-то другое было, похоже - давно дело было. Сейчас глянул старые заметки свои - 41 сек. против 30 сек.

YAR ★★★★★
()
Ответ на: комментарий от YAR

Все равно прирост на треть - это не мало. Сейчас перепиливаю свое поделие (пилю небольшую CMS) - может выложу сюда.

leg0las ★★★★★
() автор топика
Ответ на: комментарий от Harald

Для меня это было очевидно, что быстрее, просто я не думал, что настолько велика разница, да и в куче мануалов пишут коннект с помощью host:port.

leg0las ★★★★★
() автор топика
Ответ на: комментарий от leg0las

ну дак локальный IPC - это по большому счёту копирование из одного процесса в другой через промежуточный буфер, а через сетевую подсистему - разбить на пакеты, налепить заголовки, подсчитать контрольные суммы, выбрать маршрут, прогнать через правила файервола и т.д., потом всё то же самое в обратном порядке, конечно будет значительная разница

Harald ★★★★★
()

Не удивительно, оверхеда меньше, поэтому и быстрее.

umren ★★★★★
()
Ответ на: комментарий от Harald

Выбор маршрута для 127.0.0.1? Для loopback-а по идее что-то можно средать или оптимизировать. Но юникс-сокет всё-равно кошернее.

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

Но юникс-сокет всё-равно кошернее.

кстати, нарывался на такое: для ipc использовалось localhost AF_INET + SOCK_DGRAM (т.е. UDP) - на большой куче данных получали пропадания пакетов. Да, такое поведение документировано, но это было локально, видимо, по-этому, не задумывались. AF_INET было заменено на AF_UNIX - волшебным (читай, согласно документации :) ) образом все заработало

Deleted
()

Хреново, что драйвера не имеют локально работать через shared memory. Это было бы быстрее всего.

vromanov ★★★
()

если все находится локально, то лучше использовать сокет

Где-то был пример, когда такой вариант серьёзно повышал нагрузку на FS.
Сам использую, по возможности, сокеты.

Yustas ★★★★
()
Ответ на: комментарий от Yustas

Где-то был пример, когда такой вариант серьёзно повышал нагрузку на FS.

Хыхы, из-за того, что софт начинает работать быстрее при отсутствии оверхеда на сеть?

xtraeft ★★☆☆
()
Ответ на: комментарий от xtraeft

Нет, это кажется оптимизировали nginx+php-fpm, и у них при большом кол-ве соединений запросы к сокету давали ощутимую нагрузку на IO

Yustas ★★★★
()
Ответ на: комментарий от Yustas

Ого. О каком примерно количестве соединений идет речь?

xtraeft ★★☆☆
()
Ответ на: комментарий от Yustas

Очень странно. Чтобы передавать через сокет, надо проверить права, но они после первого же обращения лежат где-то в buffer cache и с диска не читаются. Работа с сокетом может повышать iowait, но диск оно трогать не должно. Можно ссылку?

selivan ★★★
()

но почему-то НИГДЕ не пишут, что если все находится локально, то лучше использовать сокет.

Да пишут. В php мануале вроде читал.

goingUp ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.