Redis 方案

redis的一些使用场景

生成单号

set集合元素是唯一且无顺序的,我们利用set集合的这一特点来做生成单号的功能。思路:先在集合中存入100万个单号,再通过命令spop myset 随机删除,并返回删除单号,当集合中的单号小于10万的时候,再生成100万个单号存入集合 … … 下面我们来实现下这个功能。

1、生成100万个单号,用时2s多一点,当然跟程序的复杂程度有关系,我这里是为了测试,比较简单

        String[] str = new String[1000000];
        for (int i = 0; i < 1000000; i++) {
            str[i] = String.valueOf(i);
        }
        jedis.sadd("myset", str);

2、随机取出一个单号,并删除集合中的该元素,spop的时间复杂度为O(1)

        String orderNo = jedis.spop("myset"); //返回302206

查看元素是否存在 ,返会0表示不存在了

127.0.0.1:6379> sismember myset 302206
(integer) 0

计数器

进行各种数据统计的用途是非常广泛的,比如想知道什么时候封锁一个IP地址。INCRBY命令让这些变得很容易,通过原子递增保持计数;GETSET用来重置计数器;过期属性用来确认一个关键字什么时候应该删除。
Redis的命令都是原子性的,可以轻松地利用INCR,DECR命令来构建计数器系统。

        jedis.set("count", "0");
        for (int i = 0; i < 1000000; i++) {
            jedis.incr("count");
        }
        System.out.println(jedis.get("count"));//1000000

GETSET key value 给key设置一个新值value,同时返回上一个值,比如统计网站访问量,初始值的时候设置为0,在更新的时候完成的数据的读取,不会丢失每一次的访问,例:

        String count1=jedis.getSet("count", "1"); //null
        String count2=jedis.getSet("count", "2"); //1
        String count3=jedis.getSet("count", "3"); //2

限制列表

冷热数据的滚动,冷数据自动滚到磁盘
主页显示一段时间访问最频繁的100个商品。redis允许我们使用一个限制列表,我们记住最新的N条数据,忽略所有的老数据,这个时候我们就可以使用LTRIM命令

        String[] items = new String[1000];
        for (int i = 0; i < 1000; i++) {
            items[i] = String.valueOf(i);
        }
        jedis.lpush("items", items);
        String value1 = jedis.llen("items");//1000
        jedis.ltrim("items", 0, 99);
        String value2 = jedis.llen("items");//100
        String value3 = jedis.lrange("items", 0, -1);//999 ... 900

限速

思路:为某一个Key设置过期60秒的过期时间,超过60秒才能重新执行,不超过60秒进行拦截, 比如短信验证码

String key = jedis.get("mykey");
if (key == null) {
     System.out.println("到期,可以发起请求");
     jedis.set("mykey", "1", "nx", "ex", 60L);
} else {
     System.out.println("还未到期");
}

任务队列

原理:生产者从list的一端插入新消息,消费者从另一端读取并移除。
Redis的列表是通过链表实现的。这意味着,即使在列表中有数以百万计的元素,也可以轻松执行在头部或尾部添加新元素的操作。不管元素有1000万个,还是只有10个,LPUSH命令的速度都是一样的。所以特别适合做消息队列。

192.168.10.138:7777> rpush mylist ok1 ok2 ok3
(integer) 3
192.168.10.138:7777> lrange mylist 0 -1
1) "ok1"
2) "ok2"
3) "ok3"
192.168.10.138:7777> lpop mylist
"ok1"
192.168.10.138:7777> lrange mylist 0 -1
1) "ok2"
2) "ok3"

文章列表

列表的用途

 lpush + lpop = Stack (栈)
 lpush + rpop = Queue (队列)
 lpush + ltrim = Capped Collection (有限集合)
 lpush + brop = Message Queue(消息队列)

dubbo用redis做注册中心

dubbo是一个分布式服务治理框架,注册中心有zookeeper、redis等。在dubbo中redis是如何实现注册中心的呢?

  • 使用 Redis 的 hash存储生产者/消费者数据
    主 Key 为服务名和类型
    Map 中的 Key 为 URL 地址
    Map 中的 Value 为过期时间,用于判断脏数据,脏数据由监控中心删除
192.168.10.151:7777> keys *
  1) "/dubbo/com.xxx.seller.member.SellerMemberLevelService/providers"
192.168.10.151:7777> hkeys /dubbo/com.xxx.seller.member.SellerMemberLevelService/providers
1) "dubbo://192.168.10.1:2608/com.xxx.seller.member.SellerMemberLevelService?anyhost=true&application=dubbo-user-provider&dubbo=3.0.0-SNAPSHOT&generic=false&interface=com.xxx.seller.member.SellerMemberLevelService&methods=getPoint,updateConsignee,findByAccountId,findCountByCondition,updateHeadImg,findByCondition,save,findOne&pid=28597&side=provider&threads=200&timestamp=1522382640798"
  • 使用 Redis 的 Publish/Subscribe 事件通知数据变更:
    通过事件的值区分事件类型:register, unregister, subscribe, unsubscribe
    普通消费者直接订阅指定服务提供者的 Key,只会收到指定服务的 register, unregister 事件
    监控中心通过 psubscribe 功能订阅 /dubbo/*,会收到所有服务的所有变更事件

  • 调用过程:
    服务提供方启动时,向 Key:/dubbo/com.foo.BarService/providers 下,添加当前提供者的地址
    并向 Channel:/dubbo/com.foo.BarService/providers 发送 register 事件
    服务消费方启动时,从 Channel:/dubbo/com.foo.BarService/providers 订阅 register 和 unregister 事件
    并向 Key:/dubbo/com.foo.BarService/consumers 下,添加当前消费者的地址
    服务消费方收到 register 和 unregister 事件后,从 Key:/dubbo/com.foo.BarService/providers 下获取提供者地址列表
    服务监控中心启动时,从 Channel:/dubbo/* 订阅 register 和 unregister,以及 subscribe 和unsubsribe事件
    服务监控中心收到 register 和 unregister 事件后,从 Key:/dubbo/com.foo.BarService/providers 下获取提供者地址列表
    服务监控中心收到 subscribe 和 unsubsribe 事件后,从 Key:/dubbo/com.foo.BarService/consumers 下获取消费者地址列表

参考文档

https://segmentfault.com/a/1190000012645123
http://blog.csdn.net/u014386474/article/details/51838190
https://blog.csdn.net/justdoithai/article/details/51393178

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值