Day17 Redis应用实战-GEO/HyperLogLog/Transaction操作

Redis 资料型态GEO

  • 储存地理空间资讯.

  • 可用指令

    • GEOADD
    • GEOPOS
    • GEODIST
    • GEORADIUS
    • GEORADIUSBYMEMBER
    • GEOHASH
  • 资料结构

    • GEO底层使用ZSET作为储存结构.

GEOADD

新增member包含位置到geo.

127.0.0.1:6379> geoadd cities 121.5598 25.09108 taipei
(integer) 1

127.0.0.1:6379> geoadd cities 121.2168 24.93759 taoyuan
(integer) 1

GEOPOS

取得geo中member的位置.

127.0.0.1:6379> geopos cities taipei
1) 1) "121.55980199575424194"
   2) "25.09107928759889461"

GEODIST

取得geo中两个member的距离.

# 预设单位为m
127.0.0.1:6379> geodist cities taipei taoyuan
"38557.7088"

# 单位为km
127.0.0.1:6379> geodist cities taipei taoyuan km
"38.5577"

# 单位为ft
127.0.0.1:6379> geodist cities taipei taoyuan ft
"126501.6694"

# 单位为mi
127.0.0.1:6379> geodist cities taipei taoyuan mi
"23.9587"

GEORADIUS

取得geo中指定位置半径内的所有member.

127.0.0.1:6379> geoadd cities 121.5598 25.09108 taipei
(integer) 1
127.0.0.1:6379> geoadd cities 121.2168 24.93759 taoyuan
(integer) 1
127.0.0.1:6379> geoadd cities 120.666 23.01087 kaohsiung
(integer) 1
127.0.0.1:6379> geoadd cities 120.2513 23.1417 tainan
(integer) 1

# 取得cities中距离在121.52250 25.03715 半径120 km 的member
127.0.0.1:6379> georadius cities 121.52250 25.03715 120 km
1) "taoyuan"
2) "taipei"

# 取得cities中距离在121.52250 25.03715 半径120 km 的member并加上位置
127.0.0.1:6379> georadius cities 121.52250 25.03715 120 km withcoord
1) 1) "taoyuan"
   2) 1) "121.21680110692977905"
      2) "24.93758924779512398"
2) 1) "taipei"
   2) 1) "121.55980199575424194"
      2) "25.09107928759889461"
# 取得cities中距离在121.52250 25.03715 半径120 km 的membe并加上距离
127.0.0.1:6379> georadius cities 121.52250 25.03715 120 km withdist
1) 1) "taoyuan"
   2) "32.7483"
2) 1) "taipei"
   2) "7.0785"
# 取得cities中距离在121.52250 25.03715 半径120 km 的member并将提供位置hash
127.0.0.1:6379> georadius cities 121.52250 25.03715 120 km withhash
1) 1) "taoyuan"
   2) (integer) 4050139696016711
2) 1) "taipei"
   2) (integer) 4050152556288054

GEORADIUSBYMEMBER

取得geo中指定member半径内的所有member.

127.0.0.1:6379> geoadd cities 121.5598 25.09108 taipei
(integer) 1
127.0.0.1:6379> geoadd cities 121.2168 24.93759 taoyuan
(integer) 1
127.0.0.1:6379> geoadd cities 120.666 23.01087 kaohsiung
(integer) 1
127.0.0.1:6379> geoadd cities 120.2513 23.1417 tainan
(integer) 1

# 取得cities中距离tainan 半径120 km的member
127.0.0.1:6379> georadiusbymember cities tainan 120 km
1) "tainan"
2) "kaohsiung"

GEOHASH

取得指定member的geo hash值.

127.0.0.1:6379> geohash cities taipei
1) "wsqqwptnhs0"

Redis 资料型态HyperLogLog

  • 当作进行基数统计的演算法.

    • 优点-当输入的元素或key很大时,计算基数所需要的空间永远固定,而且很小,每个HyperLogLog的key只需要12kb的记忆体,就能够计算接近2^64个不同元素的基数.
    • 缺点-只能用来计算元素的个数,不储存元素value,所以不能回传元素value.
  • 可用指令

    • PFADD
    • PFCOUNT
    • PFMERGE
  • 资料结构

    • GEO底层使用ZSET作为储存结构.

PFADD

新增元素到hyperloglog中.

127.0.0.1:6379> pfadd mytest abc def ghi jkl
(integer) 1

PFCOUNT

取得目前hyperloglog中元素的个数.

127.0.0.1:6379> pfadd mytest abc def ghi jkl
(integer) 1

127.0.0.1:6379> pfcount mytest
(integer) 4

PFMERGE

合并多个hyperloglog并写入到新的hyperloglog.

127.0.0.1:6379> pfadd mylog abc def ghi jkl
(integer) 1

127.0.0.1:6379> pfadd mylog2 mno pqr
(integer) 1

127.0.0.1:6379> pfcount mylog
(integer) 4

127.0.0.1:6379> pfcount mylog2
(integer) 2 

# 合并mylog与mylog2并写入mylog3
127.0.0.1:6379> pfmerge mylog3 mylog mylog2
OK

127.0.0.1:6379> pfcount mylog3
(integer) 6

Redis 资料型态BloomFilter

  • 由一组很长的二进位向量所组成,其中所储存的资料为0 or 1.主要用途在於快速判断某个元素是否存在於集合中,可以确定一定不存在,但不能确定一定存在.

    • 优点-记忆体耗用量小,新增与查询速度很快.
    • 缺点-随着资料量增加,误判率将会随之增高,且无法删除资料.
  • 可用指令

    • 需搭配RedisBloom或Guava模组

Redis Transaction

  • Redis服务器可以一次执行多个操作,执行过程部会被其他操作插入执行顺序.
  • 交易过程使用方式
    • 交易开始-mutli
    • 依照设计的交易顺序进行操作
    • 交易结束-exec

Transaction操作

实际上就是交易开始时会把所有的操作存放到QUEUE後在交易结束时一次执行.

127.0.0.1:6379> set bankaccountA 300
OK

127.0.0.1:6379> set bankaccountB 500
OK

# 帐户A原本有300
# 帐户B原本有500
127.0.0.1:6379> mget bankaccountA bankaccountB
1) "300"
2) "500"

# 交易开始
127.0.0.1:6379> multi
OK

# 从帐户B转帐到帐户A
127.0.0.1:6379(TX)> decrby bankaccountB 100
QUEUED

127.0.0.1:6379(TX)> incrby bankaccountA 100
QUEUED

# 交易结束
127.0.0.1:6379(TX)> exec
1) (integer) 400
2) (integer) 400

# 确认结果-成功
127.0.0.1:6379> mget bankaccountA bankaccountB
1) "400"
2) "400"

取消Transaction

  • 当开始交易後需要取消交易可以透过discard进行.
# 延续上面操作
127.0.0.1:6379> mget bankaccountA bankaccountB
1) "400"
2) "400"

127.0.0.1:6379> multi
OK

# 从帐户B转帐到帐户A
127.0.0.1:6379(TX)> decrby bankaccountB 200
QUEUED

127.0.0.1:6379(TX)> incrby bankaccountA 200
QUEUED

# 取消交易
127.0.0.1:6379(TX)> discard
OK

# 确认结果-无异动
127.0.0.1:6379> mget bankaccountA bankaccountB
1) "400"
2) "400"

异常Transaction

  • 当开始交易後执行异常时会发生错误,只有错误的指令不会执行,其余的指令还是会正常执行.
# 延续上面操作
127.0.0.1:6379> mget bankaccountA bankaccountB
1) "400"
2) "400"

127.0.0.1:6379> multi
OK

# 从帐户B转帐到帐户A与C各100
127.0.0.1:6379(TX)> decrby bankaccountB 200
QUEUED

# 开启帐户C给予string value
127.0.0.1:6379(TX)> set bankaccountC abc
QUEUED

# 此指令会引发失败
127.0.0.1:6379(TX)> incrby bankaccountC 100
QUEUED

127.0.0.1:6379(TX)> incrby bankaccountA 100
QUEUED

# 交易结束
127.0.0.1:6379(TX)> exec
1) (integer) 200
2) OK
3) (error) ERR value is not an integer or out of range
4) (integer) 500

# 确认结果-非预期的失败造成结果异常
127.0.0.1:6379> mget bankaccountA bankaccountB bankaccountC
1) "500"
2) "200"
3) "abc"

失败Transaction

  • 当开始交易後执行操作发生异常时,会取消所有的操作.
# 延续上面操作
127.0.0.1:6379> mget bankaccountA bankaccountB bankaccountC
1) "500"
2) "200"
3) "abc"

127.0.0.1:6379> multi
OK

# 从帐户A转帐到帐户C与B各100
127.0.0.1:6379(TX)> decrby bankaccountA 200
QUEUED

# 操作指令错误,不会被放到QUEUE
127.0.0.1:6379(TX)> setstring bankaccountC def
(error) ERR unknown command `setstring`, with args beginning with: `bankaccountC`, `def`, 

127.0.0.1:6379(TX)> incrby bankaccountC 100
QUEUED

127.0.0.1:6379(TX)> incrby bankaccountB 100
QUEUED

# 交易结束
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.

# 确认结果-由上而下执行,当错误已发生则会取消所有操作
127.0.0.1:6379> mget bankaccountA bankaccountB bankaccountC
1) "500"
2) "200"
3) "abc"

<<:  Day 17 - 取得帐务相关资讯 (下)

>>:  JavaScript Day17 - 阵列操作(map)

学习日记-2

有一小段时间没跟新了XD! 主要是平时都加班,下班去健身房回到家,就只剩1-2小时的学习时间,就慢慢...

Rust-并行&并发(一)

有关於并行和并发的定义每个人可能有不一样的解释 并行指的是在同一时刻,多条指令在 CPU 上同时执行...

第13章:分析、储存与存取系统日志介绍(一)

前言 本章节,是要讲解系统日志的架构与介绍 系统日志 在一个标准的作业系统中,会有系统日志,并分别存...

PATH 到底在干嘛呢?

对於初学者来说 PATH 听起来抽象又难懂, PATH 又是什麽呢? PATH 叫做【环境变数 En...

[Deploy to Render] 部署自己的 CodiMD/HedgeDoc

从发布第一篇 什麽是 Render 至今,转眼三个多月过去了,说好的更多范例和介绍持续 富奸 拖稿中...