文章目录

  • 概述
  • Redis 的 Hyperloglog 命令
  • Spring 中操作基数
  • 注意
  • 代码

概述

基数是一种算法。

举个例子 , 一本英文著作由数百万个单词组成,你的内存却不足以存储它们,那么我们先分析一下业务。英文单词本身是有限的,在这本书的几百万个单词中有许许多多重复单词 ,扣去重复的单词,这本书中也就是几千到一万多个单词而己,那么内存就足够存储它们 了。比如数字集合{1,2,5,7,9, 1,5,9 }的基数集合为{ 1,2,5,7,9}那么基数(不重复元素)就是 5 , 基数的作用是评估大约需要准备多少个存储单元去存储数据,但是基数的算法一般会存在一定的误差(一般是可控的)。

Redis 对基数数据结构的支持是从版本 2.8.9 开始的。

基数并不是存储元素,存储元素消耗内存空间比较大,而是给某一个有重复元素的数据集合( 一般是很大的数据集合〉评估需要的空间单元数,所以它没有办法进行存储 ,加上在工作中用得不多 ,所以简要介绍一下 Redis的HyperLogLog 命令就可以了.


Redis 的 Hyperloglog 命令

官网:https://redis.io/commands#hyperloglog

命令 说明 备注
pfadd key element 添加指定元素到 HyperLogLog 中 如果已经存储元素,则返回为 0,添加失败
pfcount key 返回 HyperLogLog 的基数值 ----
pfmerge desKey key1 [key2 key3 …] 合并多个 HyperLogLog,并将其保存在 desKey 中 ----
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379> PFADD h1 a
(integer) 1
127.0.0.1:6379> PFADD h1 b
(integer) 1
127.0.0.1:6379> PFADD h1 c
(integer) 1
127.0.0.1:6379> PFADD h1 d
(integer) 1
127.0.0.1:6379> PFADD h1 a
(integer) 0
127.0.0.1:6379> PFADD h2 a
(integer) 1
127.0.0.1:6379> PFADD h2 z
(integer) 1
127.0.0.1:6379> PFMERGE h3 h1 h2
OK
127.0.0.1:6379> PFCOUNT h3
(integer) 5
127.0.0.1:6379> 

分析一下逻辑,首先往一个键为 h1的 HyperLogLog 插入元素 ,让其计算基数,到 了第 5 个命令“ pfadd h1 a”的时候,由于在此以前已经添加过,所以返回了 0。 它 的基数集合是{a,b,c,d},因此求集合长度是4 。

之后再添加第二个基数h2,它的基数是{a,z},所以在合并h1和h2到h3中的时候,它的基数和为{a,b,c,d,z}。所以求它的基数是5.


Spring 中操作基数

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="classpath:redis/redis.properties" /><!--2,注意新版本2.3以后,JedisPoolConfig的property name,不是maxActive而是maxTotal,而且没有maxWait属性,建议看一下Jedis源码或百度。 --><!-- redis连接池配置 --><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><!--最大空闲数 --><property name="maxIdle" value="${redis.maxIdle}" /><!--连接池的最大数据库连接数 --><property name="maxTotal" value="${redis.maxTotal}" /><!--最大建立连接等待时间 --><property name="maxWaitMillis" value="${redis.maxWaitMillis}" /><!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟) --><property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}" /><!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3 --><property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}" /><!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1 --><property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}" /><property name="testOnBorrow" value="true"></property><property name="testOnReturn" value="true"></property><property name="testWhileIdle" value="true"></property></bean><!--redis连接工厂 --><bean id="jedisConnectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"destroy-method="destroy"><property name="poolConfig" ref="jedisPoolConfig"></property><!--IP地址 --><property name="hostName" value="${redis.host.ip}"></property><!--端口号 --><property name="port" value="${redis.port}"></property><!--如果Redis设置有密码 --><property name="password" value="${redis.password}" /> <!--客户端超时时间单位是毫秒 --><property name="timeout" value="${redis.timeout}"></property><property name="usePool" value="true" /><!--<property name="database" value="0" /> --></bean><!-- 键值序列化器设置为String 类型 --><bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/><!-- redis template definition --><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"p:connection-factory-ref="jedisConnectionFactory"p:keySerializer-ref="stringRedisSerializer"p:defaultSerializer-ref="stringRedisSerializer"p:valueSerializer-ref="stringRedisSerializer"></bean></beans>
package com.artisan.redis.baseStructure.hyperloglgo;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;public class SpringRedisHyperLogLogDemo {@SuppressWarnings({ "unchecked", "rawtypes", "resource" })public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring/spring-redis-hyperloglog.xml");RedisTemplate redisTemplate = (RedisTemplate) ctx.getBean("redisTemplate");// 为确保数据干净,先清除redisTemplate.delete("h1");redisTemplate.delete("h2");redisTemplate.delete("h3");// 添加指定元素到 HyperLogLog 中Long count = redisTemplate.opsForHyperLogLog().add("h1", "a", "b", "c", "d", "a");System.out.println(count);count = redisTemplate.opsForHyperLogLog().add("h2", "a");System.out.println(count);count = redisTemplate.opsForHyperLogLog().add("h2", "z");System.out.println(count);Long size = redisTemplate.opsForHyperLogLog().size("h1");System.out.println(size);Long size2 = redisTemplate.opsForHyperLogLog().size("h2");System.out.println(size2);Long size3 = redisTemplate.opsForHyperLogLog().union("h3", "h1", "h2");System.out.println(size3);Long size4 = redisTemplate.opsForHyperLogLog().size("h3");System.out.println(size4);}}

输出

INFO : org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@73a8dfcc: startup date [Thu Sep 27 00:11:19 CST 2018]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [spring/spring-redis-hyperloglog.xml]
1
1
1
4
2
5
5

注意

使用 Spring 提供的 RedisTemplate 去展示多个命令可以学习到如何使用 RedisTemplate 操作 Redis 。 实际工作中并不是那么用的,因为每一 个操作会尝试从连接池里获取 一 个新的 Redis 连接,多个命令应该使用SessionCallback 接口进行操作 。


代码

代码托管到了 https://github.com/yangshangwei/redis_learn

Redis-08Redis数据结构--基数HyperLogLog相关推荐

  1. Redis高级数据结构原理解析-bitmap,hyperloglog

    Redis 位图 开发过程中,我们可能遇到这种场景记录用户的打卡情况,签到情况,这些场景只有两种结果,有或者没有,加入记录的数据量比较大,比如用一年的数据,如果用Redis中普通key/value,每 ...

  2. Redis(十):Redis特殊类型之Hyperloglog基数统计

    redis 2.8.9版本就更新了Hyperloglog数据结构! Hyperloglog:基数统计算法!0.81%的错误率,不过统计大量数据可以忽略! 在 Redis 里面,每个 HyperLogL ...

  3. 【2. Redis 高级数据结构】

    Redis 高级数据结构 Bitmaps ​ 现代计算机用二进制(位)作为信息的基础单位,1 个字节等于 8 位,例如"big" 字符串是由 3 个字节组成,但实际在计算机存储时将 ...

  4. java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part2(Redis的数据结构)~整起

    PART1:Redis的数据结构:5+3数据类型<----------------->数据结构[未来随着 Redis 新版本的发布,可能会有新的数据结构出现,通过查阅 Redis 官网[[ ...

  5. 你真的懂redis的数据结构了吗?redis内部数据结构和外部数据结构揭秘

    Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有序集合SortedSet. 很多人面试时都遇到过这种场景吧? 其实除了上面的几种常见数据结构,还需要加上数据结 ...

  6. Redis核心数据结构ZSET、GeoHash 、 Stream--排行榜、消息Pull推送、附近搜索、布隆过滤器 、IM聊天室

    ZSET.Geo . Stream redis zset数据结构 常用命令 排行榜 步骤一.初始化1个月的历史数据 步骤二:定时刷新数据 步骤3:排行榜查询接口 GeoHash 命令 附近酒店搜索实现 ...

  7. Redis系列:Redis的数据结构

    Redis 的基本数据类型包括:二进制安全字符串 String.Hashes(哈希).Lists 列表.Sets 集合 和 Sorted sets 有序集合: Redis 的特殊数据类型还包括:geo ...

  8. Redis的数据结构及应用场景

    2019独角兽企业重金招聘Python工程师标准>>> 一. 谈谈对redis的理解,它的应用场景. Redis是一个key-value存储系统,它支持存储的value类型包括str ...

  9. redis的数据结构||1) 字符串类型2) 哈希类型3) 列表类型4) 集合类型 5) 有序集合类型详解

    2. 下载安装     1. 官网:https://redis.io     2. 中文网:http://www.redis.net.cn/     3. 解压直接可以使用:         * re ...

最新文章

  1. Linux 2 的 Windows 子系统上发布 CUDA
  2. linux 分区u盘 fdisk 简介
  3. python写扫雷脚本_Python自动扫雷实现方法
  4. adams2016安装教程
  5. java魂斗罗_java 魂斗罗
  6. List类系列(一):list中各元素出现的次数
  7. 操作系统锁的实现方法有哪几种_一文带你彻底了解同步和锁的本质
  8. java 参数理解,JAVA参数传递值传递的理解。
  9. idea 中maven编译速度过慢的问题的解决
  10. DevOps使用教程 华为云(9)代码检查
  11. python爬网站信息_爬取网页信息的小能手——微软PowerBI
  12. Android官方文档中文版
  13. php网页设计导航栏代码,CSS导航栏及弹窗示例代码
  14. CAD中怎么给设备赋值?
  15. 主成分分析法怎么提取图片中的字_论文中做出CNS高逼格的主成分分析图教程
  16. Python 实现读取文本内容、文件重命名、替换文本内容
  17. SyntaxError: Missing parentheses in call to ‘print‘. 正解
  18. 客服充值退款小套路你们会识别吗?
  19. 芒果iOS开发之百度魔图面试题
  20. 直播教育平台开发—老师学生上课学习的好帮手

热门文章

  1. 深入浅出让你理解什么是LLVM
  2. C++引用入门教程(一)
  3. 哈工大操作系统环境配置
  4. word2vector 讲的比较好的文章
  5. 119. Leetcode 115. 不同的子序列 (动态规划-子序列问题)
  6. 推荐系统中的召回算法--协同过滤
  7. 强化学习及其在NLP上的应用
  8. 手把手干货教学Matlab载波调制
  9. (经典)Hibernate的一对多关系映射(三)
  10. 结构损伤检测与智能诊断 陈长征_阜康危房检测价格