Geospatial 地理位置

朋友的定位,附近的人,打车距离计算? Redis 的 Geo 在Redis3.2 版本就推出了! 这个功能可以推算地理位置的信息,两地之间的距离,方圆几里的人!

geoadd

image-20200426110316753

image-20200426110841442

getpos

image-20200426110922309

获得当前定位:一定是一个坐标值!

image-20200426111025801

geodist

image-20200426111053222

image-20200426111221621

georadius

image-20200426111329492

以给定的经纬度为中心, 找出某一半径内的元素

image-20200426112057616

georadiusbymember

image-20200426112136336

找出位于指定元素周围的其他元素!

image-20200426112716406

geohash

image-20200426112800094

返回一个或多个位置元素的 Geohash 表示

image-20200426112843484

将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么则距离越近!

注意

GEO 底层的实现原理其实就是 Zset!我们可以使用Zset命令来操作geo!

image-20200426112958707

Hyperloglog

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

优点:占用的内存是固定,2^64 不同的元素的技术,只需要废 12KB内存!如果要从内存角度来比较的 话 Hyperloglog 首选! 网页的 UV (一个人访问一个网站多次,但是还是算作一个人!) 传统的方式, set 保存用户的id,然后就可以统计 set 中的元素数量作为标准判断 ! 这个方式如果保存大量的用户id,就会比较麻烦!我们的目的是为了计数,而不是保存用户id; 0.81% 错误率! 统计UV任务,可以忽略不计的!

什么是基数?

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

Redis HyperLogLog 命令

下表列出了 redis HyperLogLog 的基本命令:

序号 命令及描述
1 PFADD key element [element …] 添加指定元素到 HyperLogLog 中。
2 PFCOUNT key [key …] 返回给定 HyperLogLog 的基数估算值。
3 PFMERGE destkey sourcekey [sourcekey …] 将多个 HyperLogLog 合并为一个 HyperLogLog

image-20200426113353412

Bitmap

位存储

统计用户信息,活跃,不活跃! 登录 、 未登录! 打卡,365打卡! 两个状态的,都可以使用 Bitmaps! Bitmap 位图,数据结构! 都是操作二进制位来进行记录,就只有0 和 1 两个状态! 365 天 = 365 bit 1字节 = 8bit 46 个字节左右

测试:使用bitmap 来记录 周一到周日的打卡!1为打卡。0为没有打卡

setbit key offset value

image-20200426113714887

getbit key offset

查看某一天是否打卡

image-20200426113813389

bitcount key [start end]

统计操作,统计 打卡的天数!

image-20200426113844734

事务

Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:

  • 批量操作在发送 EXEC 命令前被放入队列缓存。
  • 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
  • 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

一个事务从开始到执行会经历以下三个阶段:

  • 开始事务。
  • 命令入队。
  • 执行事务。

Redis 事务本质:一组命令的集合! 一个事务中的所有命令都会被序列化,在事务执行过程的中,会按 照顺序执行! 一次性、顺序性、排他性!执行一些列的命令!

Redis事务没有没有隔离级别的概念! 所有的命令在事务中,并没有直接被执行!只有发起执行命令的时候才会执行!Exec

Redis单条命令式保存原子性的,但是事务不保证原子性!

Redis 事务命令

下表列出了 redis 事务的相关命令:

序号 命令及描述
1 DISCARD 取消事务,放弃执行事务块内的所有命令。
2 EXEC 执行所有事务块内的命令。
3 MULTI 标记一个事务块的开始。
4 UNWATCH 取消 WATCH 命令对所有 key 的监视。
5 WATCH key [key …] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

正常执行事务

image-20200426114416350

放弃事务

image-20200426114756826

编译型异常

代码有问题! 命令有错!事务中所有的命令都不会被执行!

image-20200426115313154

运行时异常

(1/0), 如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行 的,错误命令抛出异常!

image-20200426115827171

监控(Watch)

悲观锁: 很悲观,认为什么时候都会出问题,无论做什么都会加锁!

乐观锁: 很乐观,认为什么时候都不会出问题,所以不会上锁! 更新数据的时候去判断一下,在此期间是否 有人修改过这个数据, 获取version 更新的时候比较 version

正常执行

image-20200426120132416

测试多线程修改值 , 使用watch 可以当做redis的乐观锁操作!(在开一个连接)

image-20200426120449192

image-20200426120426381

如果修改失败,获取最新的值就好

image-20200426120727108