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 😊😊😊😊😊
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.