Количество статей на нашем сайте, к счастью, постоянно растет. В связи с этим появилась необходимость в создании статистики просмотров. С её помощью можно следить за посещаемостью каждой публикации и анализировать, какие темы интересны читателям.
Для разработки такой системы статистики мне посоветовали использовать Redis. Я и понятия не имел, почему. Теперь, разобравшись и прочитав различные статьи, я хочу поделиться с вами моими соображениями о том, почему стоит потратить немного времени на изучение Redis и использовать его в дальнейшем.
Кратко о Redis
Redis — хранилище данных типа «ключ-значение». Нереляционная высокопроизводительная СУБД. Хранит данные в оперативной памяти в виде словаря и умеет сохранять их на диск. На официальном сайте можно прочитать более подробную информацию, ознакомиться с документацией, а также попробовать Redis в действии.
Перечислю несколько причин, почему для решения задачи мы отдали предпочтение Key-Value хранилищу:
- Взаимодействие с данными в Redis происходит очень быстро за счет того, что он хранит их в оперативной памяти. Если предположить, что одну и ту же статью смотрит даже большое количество людей, то их просмотры фиксируются в статистике почти одновременно.
- Преимуществом Key-Value баз данных перед реляционными является их гибкость, связанная с возможностью работы без задания схемы. В частности, это значит, что не нужно заранее создавать объекты, и можно менять или добавлять их непосредственно во время работы с базой.
- Характерной чертой NoSQL является применение различных структур данных: графов, хеш-таблиц, разреженных матриц (хранилища семейств колонок), деревьев, — такие решения часто оказываются более удобными, чем привычные таблицы. Более подробно об этом — в статье на Википедии.
Как это работает
Для Redis существуют библиотеки на многих языках программирования, в том числе на PHP. Его мы и будем использовать для примера.
Статистика просмотров, по сути, представляет собой простой счетчик.
Class Stats
{
public function __construct()
{
/**
* Class_with_redis::_redis() - вызов метода класса,
* в котором происходило подключение к Redis.
*/
$this->redis = Class_with_redis::_redis();
}
public function hit($article_id)
{
$this->redis->incr('stats_article_hit:' . $article_id);
}
}
В данном примере мы создаем переменную с нулевым значением и увеличиваем его на единицу с помощью функции incr(). При последующих вызовах этой функции значение уже существующей переменной будет просто инкрементироваться. Ключом является строка, по которой производится (вернее, будет производиться) доступ к конкретной статистике. Значение - собственно, сам счетчик.
К слову об отсутствии схемы: в качестве значений в Redis можно хранить как строки, так и числа, заранее это не указывая. К примеру, у нас есть число 238, мы можем увеличить или уменьшить его при помощи команд incr(), decr(), incrby() (как в примере), а можем полностью заменить какой угодно строкой или другим числом, используя команду set(). Вот полный список команд.
Таким образом, когда пользователь открывает страницу со статьей, мы вызываем метод, в котором увеличиваем счетчик просмотров. Значения из базы мы получаем при помощи функции get().
public function get_views($article_id)
{
return $this->redis->get('stats_article_hit:' . $article_id);
}
Собственно, ничего сложного: пара строк кода, и мы уже записываем и извлекаем данные из Redis. Пожалуй, это то, на чем мы закончим знакомство с ним.