一种基于Redis的10行代码实现IP频率控制方法

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 优点:可支持海量访问的频率控制,只需要增加Redis机器,单个Redis节点(只占用一个cpu core)即可支持10万/s以上的处理。 基于IP频率限制是种常见需求,基于Redis可以十分简单实现对IP的频率限制,具体手段为利用Redis的key过期和原子加减两个特性。
优点:可支持海量访问的频率控制,只需要增加Redis机器,单个Redis节点(只占用一个cpu core)即可支持10万/s以上的处理。
基于IP频率限制是种常见需求,基于Redis可以十分简单实现对IP的频率限制,具体手段为利用Redis的key过期和原子加减两个特性。
以IP作为key,频率为key过期时长,比如限制单个IP在2秒内频率为100,则key过期时长为2秒,基于 r3c(a Redis Cluster C++ Client)的实现大致如下:

  1. r3c::CRedisClient redis("127.0.0.1:6379,127.0.0.1:6380");
  2. int ret = redis.incrby(ip, 1);
  3. if (ret > 1000) // 超过频率
  4. {
  5. }
  6. else // 访问放行
  7. {
  8.     if (1 == ret)
  9.         redis.expire(ip, 2); // 频率控制为2秒内1000次访问
  10. }

完整示例:

  1. // https://github.com/eyjian/r3c
  2. #include r3c/r3c.h>

  3. int main()
  4. {
  5.     std::string ip = "127.0.0.1";
  6.     r3c::CRedisClient redis("10.223.25.102:6379");
  7.     r3c::set_debug_log_write(NULL);
  8.     for (int i=0; i100000; ++i)
  9.     {
  10.         // r3c基于redis的EVAL命令提供了一个带过期参数的incrby,
            // 这样避免了两次操作的非原子时expire调用可能不成功问题。
  11.         int ret = redis.incrby(ip, 1);
  12.         if (ret > 1000) // 限制单个IP每2秒最多访问1000次
  13.         {
  14.             printf("[OVER] 超过频率,限制访问\n");
  15.         }
  16.         else
  17.         {
  18.             if (1 == ret)
  19.             {
  20.                 redis.expire(ip, 2); // 频率设定为2秒
  21.                 printf("[FIRST] 第一次,访问放行\n");
  22.             }
  23.             else
  24.             {
  25.                 printf("[OK] 访问放行\n");
  26.             }
  27.         }
  28.     }
  29.     redis.del(ip);
  30.     return 0;
  31. }



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
存储 缓存 NoSQL
利用Redis List实现数据库分页快速查询的有效方法
利用Redis List实现数据库分页快速查询的有效方法
|
4月前
|
设计模式 NoSQL Java
常用的设计模式以及操作Redis、MySQL数据库、各种MQ、数据类型转换的方法
常用的设计模式以及操作Redis、MySQL数据库、各种MQ、数据类型转换的方法
|
监控 NoSQL Java
云服务器Redis集群部署及客户端通过公网IP连接问题
目录 1、配置文件 2、启动服务并创建集群 (1)启动6个Redis服务 (2)通过客户端命令创建集群 3、客户端连接 (1)客户端配置 (2)测试用例 (3)错误日志分析 4、问题解决 (1)查redis.conf配置文件 (2)修改配置文件 (3)重新启动Redis服务并创建集群 5、故障转移期间Lettuce客户端连接问题 (1)测试用例 (2)停掉其中一个master节点,模拟宕机 (3)解决办法 1)更换Redis客户端 2)Lettuce客户端配置Redis集群拓扑刷新
|
7月前
|
NoSQL Java Redis
redis.clients.jedis.exceptions.JedisDataException: ERR Syntax error, try CLIENT (LIST | KILL ip:port
redis.clients.jedis.exceptions.JedisDataException: ERR Syntax error, try CLIENT (LIST | KILL ip:port
|
5月前
|
NoSQL Java Redis
Redis【应用 01】Java实现动态切换写入不同Redis数据库的方法实例(动态切换Redis数据库)
Redis【应用 01】Java实现动态切换写入不同Redis数据库的方法实例(动态切换Redis数据库)
92 0
|
5月前
|
存储 缓存 NoSQL
Redis的安装方法与基本操作
Redis是一个开源的内存数据结构存储系统,也可以用作数据库、缓存和消息中间件。它支持多种数据结构,包括字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。
87 0
Redis的安装方法与基本操作
|
6月前
|
消息中间件 缓存 NoSQL
阿里云国际站代理商:Redis实现分布式配置管理的方法与应用案例
@luotuoemo飞机@TG阿里云国际站代理商:Redis实现分布式配置管理的方法与应用案例,为了实现高可用和负载均衡,可以将Redis部署成哨兵集群或集群模式。哨兵负责监控主从节点的状态,发现故障时自动进行故障转移。集群模式可以提高系统的可扩展性,通过添加更多的从节点来分摊负载压力。
|
7月前
|
NoSQL Redis 容器
Redis集群更换节点IP后如何恢复集群并保留完整集群数据
Redis集群更换节点IP后如何恢复集群并保留完整集群数据
119 0
|
7月前
|
NoSQL Redis 容器
Redis集群报错cluster_state:fail,如何解决并重新恢复集群(IP问题/ slot未完全分配问题)
Redis集群报错cluster_state:fail,如何解决并重新恢复集群(IP问题/ slot未完全分配问题)
124 0
|
7月前
|
NoSQL 算法 API
Redis实现API访问频率限制
Redis实现API访问频率限制
62 0