Redis реализует функцию счетчика в нескольких способах (с кодом)

Redis
Redis реализует функцию счетчика в нескольких способах (с кодом)

Эта статья написанаyanglbmeОригинал, впервые опубликованный в Nuggets, несанкционированная перепечатка запрещена.

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

Пожалуйста, следуйте за мной, чтобы посмотреть.

использовать строковые ключи

В следующем коде показано, как использовать реализованную функцию счетчика строк Redis. в,incr()метод используется для накопления счетчиков,get_cnt()Метод используется для получения текущего значения счетчика.

from redis import Redis

class Counter:
    def __init__(self, client: Redis, key: str):
        self.client = client
        self.key = key

    def incr(self, amount=1):
        """计数累加"""
        self.client.incr(self.key, amount=amount)

    def decr(self, amount=1):
        """计数累减"""
        self.client.decr(self.key, amount=amount)

    def get_cnt(self):
        """获取当前计数的值"""
        return self.client.get(self.key)


if __name__ == '__main__':
    client = Redis(decode_responses=True)
    counter = Counter(client, 'page_view:12')
    counter.incr()
    counter.incr()
    print(counter.get_cnt())  # 2

Предположим, мы хотим подсчитать количество просмотров страниц с page_id 12, тогда мы можем установить ключ какpage_view:12, каждый раз, когда пользователь просматривает страницу, счетчик вызывается один разincr()метод подсчета.

использовать хэш-ключ

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

from redis import Redis

class Counter:
    def __init__(self, client: Redis, key: str, counter: str):
        self.client = client
        self.key = key
        self.counter = counter

    def incr(self, amount=1):
        """计数累加"""
        self.client.hincrby(self.key, self.counter, amount=amount)

    def decr(self, amount=1):
        """计数累减"""
        self.client.hincrby(self.key, self.counter, amount=-amount)

    def get_cnt(self):
        """获取当前计数的值"""
        return self.client.hget(self.key, self.counter)


if __name__ == '__main__':
    client = Redis(decode_responses=True)
    counter = Counter(client, 'page_view', '66')
    counter.incr()
    counter.incr()
    print(counter.get_cnt())  # 2

Если используется хэш-ключ, то мы можем использовать тот же ключ для хранения того же типа счетчика. Например, в приведенном выше примере мы используемpage_viewЧтобы подсчитать количество просмотров страниц, для страниц с page_id 66 вы можете напрямую добавить их в поле, соответствующее page_view.

Использовать ключи коллекции

В приведенных выше двух примерах, когда действие выполняется, программа может быть вызвана один раз.incr()Метод накопления отсчетов. В некоторых случаях нам может потребоваться подсчитать конкретное действие только один раз. Что такое "просто посчитай один раз"? То есть, если один и тот же пользователь/IP-адрес посещает определенную страницу несколько раз, счетчик увеличит значение счетчика только на 1. Взгляните на следующий код:

from redis import Redis

class Counter:
    def __init__(self, client: Redis, key: str):
        self.client = client
        self.key = key

    def add(self, item: str) -> bool:
        """计数累加,若计数之前item已存在,放回False;否则返回True"""
        return self.client.sadd(self.key, item) == 1

    def get_cnt(self):
        """获取当前计数的值"""
        return self.client.scard(self.key)


if __name__ == '__main__':
    client = Redis(decode_responses=True)
    counter = Counter(client, 'uv')
    counter.add('user1')
    counter.add('user2')
    counter.add('user1')  # 重复放入
    print(counter.get_cnt())  # 2

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

Добро пожаловать в мою общедоступную учетную запись WeChat «Сообщество открытого исходного кода Doocs». ​​Оригинальные технические статьи будут опубликованы как можно скорее.