redis-HyperLogLog--发布订阅

HyperLogLog

1、介绍

  • 是用来做基数统计的算法,计算基数所需的空间总是固定 的、并且是很小的。
  • 在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。
  • 不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
  • 大概有0.81%的错误率,但对于统计UV这种不需要很精确的数据是可以忽略不计的。
  • 不会记录重复的元素。

2、使用 

# 添加数据
pfadd dataA 1 2 3 4 5
# 获取总数
pfcount dataA
# 合并到dataM
pfmerge dataM dataA dataB

#例子
pfadd dataA 1 2 3 4 5
pfadd dataB a b c d e
pfmerge dataM dataA dataB
pfcount dataM 

3、java代码

@RestController
public class HelloController {

    @Autowired
    private RedisTemplate redisTemplate;

    @RequestMapping("/setLog")
    public String setRedisLog(){
        HyperLogLogOperations vo = redisTemplate.opsForHyperLogLog();
        vo.add("dog","a","b","c");
        vo.add("cat","1","2","4");

        System.out.println(vo.size("dog"));
        System.out.println(vo.size("cat"));
        vo.union("animal","dog","cat");
        System.out.println(vo.size("animal"));

        return "ok";
    }
}

发布订阅

# 用于将信息发送到指定的频道
PUBLISH channel message
# 用于查看订阅与发布系统状态,它由数个不同格式的子命令组成
PUBSUB < subcommand > argument [argument1 ....]

# 订阅一个或多个符合给定模式的频道,每个模式以*作为匹配符
PSUBSCRIBE pattern [pattern1 ....]
# 用于退订所有给定模式的频道
PUNSUBSCRIBE pattern [pattern1 ....]

# 用于订阅给定的一个或多个频道的信息
SUBSCRIBE channel [channel1 ...]
#用于退订给定的一个或多个频道的信息
UNSUBSCRIBE channel [channel1 ...]

java使用

pom

        
            org.springframework.boot
            spring-boot-starter-data-redis
        

        
            org.apache.commons
            commons-pool2
        

properties

# REDIS
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址 (默认为127.0.0.1)
spring.redis.host=192.168.206.83
# Redis服务器连接端口 (默认为6379)
spring.redis.port=6360
# Redis服务器连接密码(默认为空)
spring.redis.password=123456
# 连接超时时间(毫秒)
spring.redis.timeout=5000ms
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.min-idle=16
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.lettuce.pool.max-wait=5000ms
# 连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.lettuce.pool.max-active=3

redisTemplate配置

@Configuration
public class RedisConfig {

    /**
     * 内存占用较大,速度最快,可读性好
     * key StringRedisSerializer
     * value jackson2JsonRedisSerializer
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate getRedisTemplate(RedisConnectionFactory factory) {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.setKeySerializer(new StringRedisSerializer()); // key的序列化类型

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // value的序列化类型
        return redisTemplate;
    }
}

接收类

public abstract class AbstractReceiver {
    public abstract void receiveMessage(Object message);
}
public class GoodsReceiver extends AbstractReceiver {
    Logger log = LoggerFactory.getLogger(GoodsReceiver.class);

    @Override
    public void receiveMessage(Object message) {
        log.info("Goods接收到商品消息:{}", message.toString());
    }
}
public class UserReceiver extends AbstractReceiver {
    @Override
    public void receiveMessage(Object message) {
        System.out.println("User 接收到用户消息:{}" + message.toString());
    }
}

 消息类

public class RedisMessage implements Serializable {
    public String msgId;
    public long createStamp;
}
public class GoodsMessage extends RedisMessage {
    private String goodsType;
    private String number;
}
public class GoodsMessage extends RedisMessage {
    private String goodsType;
    private String number;

 发送消息方法

@Service
public class Publisher {
    private final RedisTemplate redisMessageTemplate;

    @Autowired
    public Publisher(RedisTemplate redisMessageTemplate) {
        this.redisMessageTemplate = redisMessageTemplate;
    }

    public void pushMessage(String topic, RedisMessage message) {
        redisMessageTemplate.convertAndSend(topic,message);
    }
}

 配置-监听绑定

@Configuration
public class ReceiverConfig {

    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter userListenerAdapter, MessageListenerAdapter goodsListenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(userListenerAdapter, new PatternTopic("user"));
        container.addMessageListener(goodsListenerAdapter, new PatternTopic("goods"));
        return container;
    }

    @Bean
    public MessageListenerAdapter userListenerAdapter(UserReceiver receiver) {
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }

    @Bean
    public MessageListenerAdapter goodsListenerAdapter(GoodsReceiver receiver) {
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }

    @Bean
    public UserReceiver userReceiver() {
        return new UserReceiver();
    }

    @Bean
    public GoodsReceiver goodsReceiver() {
        return new GoodsReceiver();
    }

}

 

参考

https://www.jianshu.com/p/8c391d025f20

你可能感兴趣的:(redis)