redis 高级 - JiyangM/spring GitHub Wiki

BloomFilter

场景:

  • hadoop大数据去重:

在MapReduce流程中,map的输出<key,value>经过shuffle过程聚集成<key,value-list>后会交给reduce。所以从设计好的reduce输入可以反推出map的输出key应为数据,value任意。继续反推,map输出数据的key为数据,而在这个实例中每个数据代表输入文件中的一行内容,所以map阶段要完成的任务就是在采用Hadoop默认的作业输入方式之后,将value设置为key,并直接输出(输出中的value任意)。map中的结果经过shuffle过程之后交给reduce。reduce阶段不会管每个key有多少个value,它直接将输入的key复制为输出的key,并输出就可以了(输出中的value被设置成空了)。

  • kafka重复消费:

Kafka的Producer和Consumer端的配置是异步且保证不丢消息,因此当超时发生时,就可能会导致消息的重发或者重复消费,需要在消费环节保证幂等。

  • 信鸽设备推送:防止重复推送

  BloomFilter是利用类似位图或者位集合数据结构来存储数据,利用位数组来简洁的表示一个集合,并且能够快速的判断一个元素是不是已经存在于这个集合。因为基于Hash来计算数据所在位置,所以BloomFilter的添加和查询操作都是O(1)的。因为存储简洁,这种数据结构能够利用较少的内存来存储海量的数据。那么,还有这种时间和空间两全其美的算法?当然不是,BloomFilter正是它的高效(使用Hash)带来了它的判断不一定是正确的,也就是说准确率不是100%。因为再好的Hash都是存在冲突的,这样的话同一个位置可能被多次置1。这样再判断的时候,有可能一个不存在的数据就会误判成存在。但是判断存在的数据一定是存在的。这里需要注意的是这里的Hash和HashMap不同,HashMap可以使用开放定址发、链地址法来解决冲突,因为HashMap是有Key-Value结构的,是可逆的,可以定位。但是Hash是不可逆的,所以不能够解决冲突。虽然BloomFilter不是100%准确,但是可以通过调节参数,使用Hash函数的个数,位数组的大小来降低失误率。这样调节完全可以把失误率降低到接近于0。可以满足大部分场景了。

利用guava实现的64位哈希映射函数把对象key打散成二进制字节数组
再对字节数组分别取低八位和高八位字节进行hash,得到2个hash值
利用hash值,2次取模获取offset,对redis的bit位设1

参考 https://www.cnblogs.com/wxisme/p/5742456.html

http://www.10tiao.com/html/674/201712/2656596293/3.html

https://juejin.im/post/5c43f695e51d455221611728


HyperLogLog

场景:可以去重、计数

pfadd、pfcount、pfmerge

参考 http://jinguoxing.github.io/redis/2018/10/10/redis-HyperLogLog/


Geo

场景:将用户给定的地理位置信息储存起来, 并对这些信息进行操作。

摇一摇、查找附近的人

参考 http://blog.huangz.me/diary/2015/redis-geo.html


Pub/Sub

“发布/订阅”在redis中,被设计的非常轻量级和简洁,它做到了消息的“发布”和“订阅”的基本能力;但是尚未提供关于消息的持久化等各种企业级的特性。

  • 一个Redis client发布消息,其他多个redis client订阅消息,发布的消息“即发即失”,
  • redis不会持久保存发布的消息;
  • 消息订阅者也将只能得到订阅之后的消息,通道中此前的消息将无从获得。

分布式锁

场景: 投标 、分布式环境数据一致性解决方案

 Jedis jedis = jedisPool.getResource();
        JedisLock lock = new JedisLock(jedis, LOCK_USER_VIP_INFO_INIT + userId);
        try {
            boolean acquire = lock.acquire();
            // do something
            if (!acquire)
                throw new LongDaiException("获取锁失败!");

            return upgradeLevel(userId);

        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
        } finally {
            //业务最后释放锁
            lock.release();
            jedisPool.returnResource(jedis);
        }

RedisSearch

RediSearch是一个高性能的全文搜索引擎,可作为一个Redis Module 运行在Redis上,是由RedisLabs团队开发的。

⚠️ **GitHub.com Fallback** ⚠️