All streams
Search
Write a publication
Pull to refresh
69
0
Александр Календарев @akalend

Ламер с 20 летнем стажем

Send message
Просто по опыту скажу, что мемкешед более подходящее решение, так как сам написал пару оберток к существующим key/value (Sophia & Tokyo). Скажу больше, у нас в компании большинство демонов общаются с фронтэндом используя мемкешовый протокол. А недостаточную функциональность просто расширяем, добавляя префикс к ключам, или иным способом.
Например мультидел для ключей 123,456 и 789 можно реализовать так:
delete 123,456,789

в клиент передаем строку «123,456,789» которая не противоречит концепции ключа.

Принципиально, можно поддерживать два и более протоколов, как реализовано, например, в TokyoTyrant или тот же мемкеш поддерживает текстовый и бинарный протокол.
Добро пожаловать в мир Key/Value ;),

На мой взгляд, было бы очень логично использовать мемкешовый протокол. Есть куча готовых клиентов.
Хотя в проектах можно использовать и курл…

спаисбо за разработку…
Ну, как показывает практика, сама libmysql написана через Ж..., и для её использования в много-тредовом режиме приходится делать танцы с бубнами. Багрепорты не помогают…
Более 5 лет использую mysqli и узнал кое-что новое
как говорится «век живи — век учись»
а вообще-то ман в руки и с флагом по жизни!
спасибо за статью

интересно, а с каких пор в маил-ру есть РНР-ные проекты?
ни чего удивительно, в духа Хабра-туториала
В книге П.Зайцева «Оптимизация производительности Мускуля» даны рекомендации:
если в ваших данных иди (id > 0) заведомо в пределах
256 то используйте TINYINT,
в пределах 64K — SMALLINT
в пределах 16М — MEDIUMINT
в пределах 2G — INT
иначе BIGINT
это экономит место, память под индекс и соответственно время на поиск.
естественно, по инту ищет быстрее.
в общем очень рекомендую эту книгу.

Тут есть разные подходы. Например, если в Мамба или Баду все данные одного пользователя хранятся на одной шарде, т.е. физически на одном сервере, то у нас исторически сложился немного иной подход, распределение по функциональному назначению: профиля хранятся на группе серверов Профиля, фотоальбомы в группе серверов Фотоальбомы, сообщения… и т.д. распределение между серверами, кроме системы сообщений, чисто классическое: остаток от деления UID на кол-во серверов.
В системе сообщений, ранее была такая же система, пока мы не столкнулись с проблемой переполнения БД. Пришлось заняться перепроектированием.
инфа из первых уст разработчиков, или есть другие источники?
тоже так можно,
почти так сделано в Топфейс
нет… есть конфиг:
сервер 1, на нем расположены три базы…
BD_1 10
BD_2 10
BD_3 10

сервер 2
BD_4 15
BD_5 15

сервер 3
BD_6 10
BD_7 10
BD_8 10

вторая цифра это вес… относительно которых мы и распределяем данные. как видно на сервера 2 данных всего две БД, а сумарный вес там такойже как на остальных серверах. Если заканчивается место, то мы выставляем вес в ноль.

Второе. на каждой шарде свой индивидуальный инкремент.
Как упоминалось в статье и я упоминал в комментариях возможно решение со сквозным UID по всем шардам. Но мы такое не практикуем.
номер шарды сообщения хранится в таблице контактов, и там же хранится номера таблиц…
т.е мы имеем информацию в каких таблицах содержится диалог только в одной записи (можно сделать в нескольких, это же RDBM)
Немного не так… раз мы определили, что сообщения хранятся на шарде N, то все сообщения и лежат на этой вот шарде. Только мы в данной БД наращиваем кол-во таблиц приблизительно одинаковой размерности.

Тут наверно необходимо рассказать подробнее про структуру хранения. У нас введено понятие диалога и диалоги двух лиц лежат на одной шарде. А в случае, как описано выше, нужно сообщения хранить дважду, один экземпляр на шарде одного и второй на шарде второго пользователя
Мы хранимм 10М строк и скорость доступа нас вполне устраивает. В старой системе у нас были триллионы записей и система так же работала.

например в Баду и Топфейсе считают цифру 100К
некоторым неудобством является отслеживанием в скрипте соединений, которые хранятся в массиве. По конфмгу выбираем по номеру шарды -> номер сервера, на котором находится данная шарда

преимущество — мы можем очень оперативно двигать такие шардя с одного физического сервера на другой
а вот таблица создается с проддолжением старого автоинкремента
CREATE TABLE IF NOT EXISTS %s.`messages_%d` (
		`id` int(20) unsigned NOT NULL AUTO_INCREMENT,
		... 
		`data` varchar(1024) DEFAULT NULL,
		PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=%d
для определение текущего автоинкремента использую следующий SQL

SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='message_%d' AND TABLE_SCHEMA='%s'"
Перераспределение данных тривиально: mysqldump -h localhost db <таблицa> --where «uc_account=123» > mysql -h SH2 db

хм… с моими размерами неделю будешь дамп делать :)
Я где-то так и поступил… хранилище быстрое, см habrahabr.ru/post/232845/#comment_7870285
хранение UID должно быть сквозное, либо в key/value либо в какой-то центральной БД
Вышеописанные случае хороши, с вышеописанными проблемами.

У меня архитектура шардинга следующая:
— каждый шард ( в моем случае это БД, которых может быть несколько на одном инстансе MySQL) имеет некий вес, пропорционально которому распределены uid
— генерим случайный номер шарды в соответствии с заданным распределением
— запоминаем в key/value хранилище, какому uid соответсвует какая шарда.

В случае добавления новой шарды, мы лишь поправляем конфиг, раздвигая диапазон шард.
В случае заканчивании места на одной из шард, мы ей выставляем вес 0 и она выбывает из баз, куда добавляются новые данные.

Вообще я использую комбинированный шардинг. Для хранения контактов, в одной шарде (алгоритм выбора шарды описан выше) используется несколько таблиц: contact_1....contact_N
их кол-во захардкожено константой. Номер таблицы определяется как uid % N.

Далее хранение сообщений. Здесь работает принцип автоинкрементных таблиц, т.е. таблица должна быть не более 10M записей (у кого-то это 100K), messages_0… messages_M
Если uid записи в пределах 0-10М., то это таблица messages_0, 10М-20М — таблица 1. и т.д.
Как только подходим к порогу (M+1) * 10M — Lim — то генерим новую таблицу. Как правило — константа Lim = 20-30 cообщений, т.е. где-то за сек до инкрементации числа M (номер таблицы в данной шарде)

Принципильно можно написать более подробную статью, готов выслушать комментарии

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Date of birth
Registered
Activity

Specialization

Software Architect, Database Architect
Lead
From 325,000 ₽
PostgreSQL
Golang
C++
Python
Database
Designing application architecture
Creating project architecture
Database design
Object-oriented design
Code Optimization