#c# #php #c #python #memcached
#c# #php #c #python #memcached
Вопрос:
Я работаю над системой, компоненты которой написаны на следующих языках:
- C
- C
- C#
- PHP
- Python
Все эти компоненты используют (редко изменяющиеся) данные, которые поступают из одного источника и могут быть кэшированы и доступны из memcache по соображениям производительности.
Поскольку разные типы данных могут храниться по-разному с помощью разных языковых API для memcache, мне интересно, было бы лучше хранить ВСЕ данные в виде строки (объекты будут храниться в виде строки JSON).
Однако это само по себе может создавать проблемы, поскольку строки (почти наверняка) имеют разные внутренние представления на разных языках, поэтому мне интересно, насколько мудрым является это решение.
Кроме того, я использую 1 writer, шаблон нескольких читателей, поэтому параллелизм не является проблемой.
Может ли кто-нибудь (желательно с РЕАЛЬНЫМ опытом выполнения чего-то подобного) посоветовать наилучший формат / способ хранения данных в memcache, чтобы они могли использоваться разными языками программирования?
Комментарии:
1. Любой сериализатор JSON (или любого формата обмена данными) (de), вероятно, будет знать, как работать с потоком символов / байтов известной кодировки символов, а «конечный поток байтов» имеет одинаковое представление в любом месте.
Ответ №1:
я думаю, что memcached в первую очередь понимает только byte[], а представление byte одинаково на всех языках. Вы можете сериализовать свои объекты, используя буферы протокола или аналогичную библиотеку, и использовать ее на любом другом языке. Я делал это в своих проектах.
Комментарии:
1. Похоже, что буферы протокола не имеют привязки к PHP (или C #). Я полагаю, я мог бы написать SWIG-обертки вокруг PB, но я не уверен, хочу ли я взять на себя эту задачу, особенно если существует более простое решение…
Ответ №2:
Независимо от выбранного серверного интерфейса (memcached, mongodb, redis, mysql, почтовый голубь) наиболее быстрым и эффективным способом хранения данных в нем будет простой блок данных (поэтому серверная часть не знает об этом.) string
byte[]
, Действительно ли это BLOB
всето же самое.
Для каждого языка потребуется согласованный механизм преобразования объектов в формат сохраняемых данных и обратно. Вы:
- Не следует создавать свой собственный механизм, это просто изобретение колеса.
- Следует подумать о том, могут ли «недопустимые» объекты оказаться в серверной части. (либо из-за ошибки в записи, либо из-за того, что объекты из предыдущей версии все еще присутствуют)
Когда дело доходит до выбора формата, я бы рекомендовал два: JSON или буферы протокола. Это связано с тем, что их размер и скорость кодирования / декодирования являются одними из самых маленьких / быстрых из всех доступных кодировок.
Сравнение
JSON:
- Библиотеки, доступные для десятков языков, иногда часть стандартной библиотеки.
- Очень простой формат — читаемый человеком при сохранении, доступный для записи человеком!
- Не требуется координации между различными системами, просто соглашение о структуре объекта.
- Нет необходимости в настройке на многих языках, например, PHP:
$data = json_encode($object); $object = json_decode($data);
- Нет встроенной схемы, поэтому читателям необходимо проверять декодированные сообщения вручную.
- Занимает больше места, чем буферы протокола.
Буферы протокола:
- Инструменты генерации, предоставляемые для нескольких языков.
- Минимальный размер — трудно превзойти.
- Определенная схема (извне) через
.proto
файлы. - Автоматически генерируемые объекты интерфейса для кодирования / декодирования, например, C :
person.SerializeToOstream(amp;output);
- Поддержка различных версий объектных схем для добавления новых
optional
элементов, так что существующие объекты не обязательно становятся недействительными. - Недоступно для чтения или записи человеком, поэтому, возможно, сложнее отлаживать.
- Определенная схема вносит некоторые накладные расходы на управление конфигурацией.
Юникод
Когда дело доходит до поддержки Unicode, оба обрабатывают ее без проблем:
- JSON: обычно экранирует символы, отличные от ascii, внутри строки as
uXXXX
, поэтому проблем с совместимостью нет. В зависимости от библиотеки также может быть возможно принудительное использование кодировки UTF-8. - Буферы протокола: похоже, используют UTF-8, хотя я не нашел информации об этом в документации Google буквами высотой 3 фута.
Краткие сведения
Какой из них вы выберете, будет зависеть от того, как именно будет вести себя ваша система, как часто происходят изменения в структуре данных и как все вышеперечисленные моменты повлияют на вас.
Ответ №3:
Не буду врать, вы могли бы сделать это в redis. Redis — это база данных типа «ключ-значение», написанная для обеспечения высокой производительности. она позволяет передавать данные между языками с использованием нескольких различных клиентских библиотек. Вот пример клиентских библиотек на Java и python
Редактировать 1: код не проверен. Если вы обнаружите ошибку, пожалуйста, дайте мне знать 🙂
Редактировать 2: я знаю, что я не использовал предпочтительный клиент redis для java, но суть все еще остается в силе.
Python
import redis
r = redis.Redis()
r.set('test','123')
Java
import org.jredis.RedisException;
import org.jredis.ri.alphazero.JRedisClient;
import static org.jredis.ri.alphazero.support.DefaultCodec.*;
class ExampleCode{
private final JRedisClient client = new JRedisClient();
public static void main(String[] args) throws RedisException {
System.out.println(toStr(client.get('test')))
}
}
Комментарии:
1. Это база данных в памяти?. Вся идея кэширования в центральном репозитории заключалась в том, чтобы обойти узкое место диска / ввода-вывода.
2. Вы можете изменить его, чтобы никогда не записывать на диск 🙂 Всего одна маленькая строка .conf
3. Улучшит ли это скорость записи? Я слышал, что Redis имеет более низкую скорость записи по сравнению с Memcached
4. Только после этого он должен записываться в память (я думаю, как сокет), и это улучшается в следующей версии redis