• Redis-三种数据结构与事务


    一、Geospatial 地理位置

    定位,附近的人,打车距离计算,学生请假还假打卡时判断是否在学校中

    Redis的geo在3.2就推出了,这个功能可以推算地理位置的信息,两地之间的距离

    geoadd 添加地理位置  
    geoadd key 纬度 经度 名称
    # 规则:无法直接添加两极,南极北极,一般正常情况下城市数据是直接录入的
    geoadd china:city 116.40 39.90 beijing # china:city是我们的key
    geoadd china:city 121.47 31.23 shanghai
    geoadd china:city 106.50 29.53 chongqin
    geoadd china:city 114.05 22.52 shenzhen
    geoadd china:city 120.16 30.24 hangzhou
    geoadd china:city 108.96 34.26 xian
    
    geopos 获取城市的地理位置,获取纬度和经度,一定是一个坐标值
    geopos china:city beijing chongqin  # 可以拿一个也可以多个
    
    geodist 返回两个给定位置之间的距离
    geodist china:city beijing shanghai 默认单位是米,返回直线距离
    geodist china:city beijing shanghai km 将单位设置为km
    
    georadius  以给定的的经纬度为中心,找到一个半径内的元素
    georadius china:city 110 30 500 km # 找110 30这个经纬度为中心,半径500km内的
    georadius china:city 110 30 500 km withdist 显示在中心位置的距离
    georadius china:city 110 30 500 km withdist withcoord count 1 # 只找一个
    比如附近的人这种功能,可以使用这种
    
    georadiusbymember 找出位于指定元素周围的其他元素
    georadiusbymember China:city beijing 500km
    

    geo底层实现原理其实就是zset,我们可以使用zset来操作geo

    比如我们可以用zset的方法删除某个地理位置
    zrange china:city 0 -1
    zrem china:city beijing 删除北京
    

    二、Hyperloglog

    是一种数据结构,用来做基数统计的算法

    优点:占用内存是固定的,2^64个不同的元素的计数(long数据类型的最大值),只需要12kb的内存。官方统计有0.81%的误差率。但是一般情况下我们是可以接受这个误差的。

    统计网页的UV(网址的访问量),一个人访问一个网站多次,但是还算一个人的访问。

    传统方法用set来保存用户的id,因为set不允许重复。然后统计set中的元素数量。当然在高并发场景下我们允许一定的误差。这个方式保存了大量的用户id,但我们的目的仅仅只是为了计数,这种方案就不太好。

    使用hyperloglog

    PFadd key1 1 2 3 4 5 # 创建key
    pfcount key1 # pfcount统计的就是基数的数量
    
    PFadd key2 4 5 6 7 8
    pfcount key2
    
    pfmerge key3 key1 key2  # 合并两组,key3是一个并集
    pfcount key3
    

    如果不允许有误差,就使用set或者自己的方法,但是要权衡内存的问题

    三、Bitmap

    位存储

    位图,也是一种数据结构,都是操作二进制来进行记录,只有0或者1的状态。

    统计用户信息,比如活跃或者不活跃,登录与未登录,365打卡,等等只有两个状态的情景

    比如365天打卡,365天=365bit 1字节=bit 相当于我们只需要45字节左右就可以记录
    一个人一年的打卡情况,比如1是打卡,0没有打卡,以下为记录一个人一周的打卡情况
    setbit user:1 0 1  # 周一
    setbit user:1 1 0  # 周二
    setbit user:1 2 1
    setbit user:1 3 0
    setbit user:1 4 1
    setbit user:1 5 1
    setbit user:1 6 1
    
    getbit user:1 3  看周四是否打卡
    
    统计打卡天数
    bitcount user:1 统计一周打卡几天,之后我们就可以进行判断看是否要扣钱
    bitcount user:1 0 4 统计周一到周五打卡天数
    

    四、事务

    redis的事务本质:一组命令的集合,一个事务中的所有命令都会被序列化,在事务的执行过程中,按照顺序执行。相当于有一个队列,其中有命令1,命令2,命令3.

    所以redis的事务有一次性,顺序性,排他性(即单个命令不能被打断)

    redis的单条命令是保证原子性的,但是redis的事务不能保证原子性。

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

    redis可以实现乐观锁

    正常执行事务流程:

    multi 开启事务
    exec  执行事务
    
    multi
    set k1 v1
    set k2 v2
    get k2
    set k3 v3
    exec
    

    放弃事务:

    multi
    set k4 v4
    discard
    放弃之后其中的代码不会执行
    

    编译型错误:

    当运行事务过程中,出现编译型错误时,比如其中某一条命令写错了,那么所有这个事务中的所有命令都不会执行。

    当运行时异常:

    当出现运行异常,比如出现了逻辑错误(比如1/0这种),那么只能那一条命令失败,其他命令会照常运行,所以redis的事务无法保证原子性。

  • 相关阅读:
    bzoj 3438 小M的作物
    洛谷 1126 机器人搬重物
    hdu 4055 Number String
    顺序对齐
    codevs 1300 文件排版
    NOIP 2015 提高组 Day2
    poj 2484 A Funny Game
    51nod 1548 欧姆诺姆和糖果 (制约关系优化枚举)
    hdu 1907 John (anti—Nim)
    hdu 2516 取石子游戏 (斐波那契博弈)
  • 原文地址:https://www.cnblogs.com/chiyun/p/14075970.html
Copyright © 2020-2023  润新知