GEO

存储经纬度,计算两个点之间的距离,统计某个点周围多少距离的其他点

北京:116.28,39.55

天津:117.12,39.08

可以计算天津到北京的距离,天津周围50km的城市,外卖等

5个城市纬度

城市 经度 纬度 简称
北京 116.28 39.55 beijing
天津 117.12 39.08 tianjin
石家庄 114.29 38.02 shijiazhuang
唐山 118.01 39.38 tangshan
保定 115.29 38.51 baoding
geoadd key longitude latitude member
举例:
geoadd cities:locations 116.28 39.55 beijing 
  
--你实际的项目,地理位置信息从哪里来的?前端传过来的
    -app,移动端,申请权限,用户允许了,直接调用手机提供的接口,得到经纬度---》调后台接口传给你--》拿到经纬度,放到redis中即可
  (网页也是,问是否允许访问你的位置,选是返回后端)
# 我现在是张三,我跟李四是朋友---》李四所在的位置,李四距离我多远,我方圆5公里内,我的好友有谁 取出某个位置的坐标 (把经纬度通过接口给前端, 前端自己处理。或者用post模块调网上现成接口[很多]显示是哪里,再给前端) geopos cities:locations beijing 计算两个人之间的距离(算的是直线距离) geodist cities:locations beijing tianjin km 计算方圆多少公里内有谁(可以算房源,商铺,好友) georadiusbymember cities:locations beijing 150 km type cities:locations # 查看geo是什么类型,返回zset,是有序集合类型

相关命令

geoadd key longitude latitude member #增加地理位置信息
geoadd cities:locations 116.28 39.55 beijing #把北京地理信息天津到cities:locations中
geoadd cities:locations 117.12 39.08 tianjin
geoadd cities:locations 114.29 38.02 shijiazhuang
geoadd cities:locations 118.01 39.38 tangshan
geoadd cities:locations 115.29 38.51 baoding
    
geopos key member #获取地理位置信息
geopos cities:locations beijing #获取北京地理信息

geodist key member1 member2 [unit]#获取两个地理位置的距离 unit:m(米) km(千米) mi(英里) ft(尺)
geodist cities:locations beijing tianjin km #北京到天津的距离,89公里

georadius key logitude latitude radiusm|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key][storedist key]

georadiusbymember key member radiusm|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key][storedist key]
#获取指定位置范围内的地理位置信息集合
'''
withcoord:返回结果中包含经纬度
withdist:返回结果中包含距离中心节点位置
withhash:返回解雇中包含geohash
COUNT count:指定返回结果的数量
asc|desc:返回结果按照距离中心店的距离做升序/降序排列
store key:将返回结果的地理位置信息保存到指定键
storedist key:将返回结果距离中心点的距离保存到指定键
'''
georadiusbymember cities:locations beijing 150 km
'''
1) "beijing"
2) "tianjin"
3) "tangshan"
4) "baoding"
'''

总结

3.2以后版本才有

geo本质时zset类型

可以使用zset的删除,删除指定member:zrem cities:locations beijing

 

redis持久化

#1 持久化:把内存中的数据,保存到硬盘上
#2 两种方案:
    -快照:rdb  (类似mysql中的Dump,把内存中所有数据存到硬盘中)
    -日志:aof     (每加,修改一条记录,记一条日志。用来恢复数据,从头走一遍即可恢复)

RDB

Redis2 GEO, redis持久化(rdb,aof), redis主从, redis哨兵

# 3 rdb持久化:三种方式,两种手动,一种配置文件(配置文件)
    # 第一种:在redis-cli客户端敲save---》通过rdb方案持久化到硬盘上,同步操作,会造成redis的阻塞
    #    (文件策略:如果老的RDB存在,会替换老的)
      # 第二种:在redis-cli客户端敲bgsave---》通过rdb方案持久化到硬盘上,异步操作
    #    (文件策略:跟save相同,如果老的RDB存在,会替换老的)
    # 第三种:配置文件
    save   900        1
    save   300        10
    save   60         10000
    解释:
    如果60s中改变了1w条数据,自动生成rdb,自动调用一下bgsave
    如果300s中改变了10条数据,自动生成rdb,自动调用一下bgsave
    如果900s中改变了1条数据,自动生成rdb,自动调用一下bgsave
    
    # 配置文件中加入:
    save 900 1 #配置一条
    save 300 10 #配置一条
    save 60 10000 #配置一条
    dbfilename dump.rdb  # 设置启动载入的rdb文件名字,这句不写默认为dump.rdb  
    dir ./ #rdb文件存在当前目录
# 4 rdb方案有缺陷,可能会丢失数据(只是用缓存)

Redis2 GEO, redis持久化(rdb,aof), redis主从, redis哨兵删除对应文件,对应aof,rdb方式无法恢复

AOF

# 5 aof持久化方案
## AOF介绍:客户端每写入一条命令,都记录一条日志,放到日志文件中,如果出现宕机,可以将数据完全恢复

## aof的三种策略
日志不是直接写到硬盘上,而是先放在缓冲区,缓冲区根据一些策略,写到硬盘上
always:redis--》写命令刷新的缓冲区---》每条命令fsync到硬盘---》AOF文件    #耗费资源,每一条命令,调flash
everysec(默认值):redis——》写命令刷新的缓冲区---》每秒把缓冲区fsync到硬盘--》AOF文件 #每秒刷一次(一般用这个)
no:redis——》写命令刷新的缓冲区---》操作系统决定,缓冲区fsync到硬盘--》AOF文件 #类似python读写文件,没调flash,由系统决定
    
# 6 aof重写
随着命令的逐步写入,并发量的变大, AOF文件会越来越大,通过AOF重写来解决该问题
本质就是把过期的,无用的,重复的,可以优化的命令,来优化
这样可以减少磁盘占用量,加速恢复速度

# 7 启用aof就是修改一下配置文件(重启即可)
  appendonly yes #将该选项设置为yes,打开
  # appendfilename "appendonly-${port}.aof" #文件保存的名字(指定aof文件名字)
  appendfilename "appendonly.aof" #文件保存的名字(指定aof文件名字)
  appendfsync everysec #采用第二种策略
  dir /bigdiskpath #存放的路径
  no-appendfsync-on-rewrite yes #在aof重写的时候,是否要做aof的append操作,因为aof重写消耗性能,磁盘消耗,正常aof写磁盘有一定的冲突,这段期间的数据,允许丢失(重写策略,是否开启)

## 公司里可以aof rdb同时使用,就是耗费性能

  自动化运维系统,自动安装redis,修改配置文件,
  给redis使用aof的持久化方案
  点按钮,切换成aof----》打开配置文件---》把那几行写入---》重启redis服务
  
  点个按钮即可

 

redis主从

# 1 为了提高性能,扩展机器(读写分离,数据副本。一主一从,一主多从)
# 2 数据流向是单向的,从master到slave
# 3 两种方式:(需要两台机器)(启动两个redis进程,分别监听两个端口)
-第一种:在客户端cli里执行命令
      -在本地起两个redis服务(进程)6380是从,6379是主
            # 6380从库基础配置修改如下
            ## port 6380    # 修改端口
            ## dir "/opt/soft/redis/data1"    # 修改数据存放目录
            ## logfile 6380.log    # 修改log文件名
            # 监测两个redis进程起来没   ps aux|grep redis-server
            ## grep --color=auto redis-server 这是监测的进程
    -登陆到从库(6380库, redis-cli -p 6380),执行 
      -slaveof 127.0.0.1 6379  # 主库增删该数据,从库跟着改(在从库写入数据会报错)
      
    -取消复制:slaveof no one
      
      
-第二种:配置文件
    -在从节点(从数据库)配置(重启即可)
          slaveof ip port #配置从节点ip和端口
        slave-read-only yes #从节点只读,因为可读可写,数据会乱
      
          slaveof 127.0.0.1 6379
        slave-read-only yes
# 4 一主多从呢?(从库只能读)
    只需要在多个从库上配置即可

 

redis哨兵

架构说明

可以做故障判断,故障转移,通知客户端(其实是一个进程),客户端直接连接sentinel的地址

Redis2 GEO, redis持久化(rdb,aof), redis主从, redis哨兵

1 多个sentinel发现并确认master有问题

2 选举触一个sentinel作为领导

3 选取一个slave作为新的master

4 通知其余slave成为新的master的slave

5 通知客户端主从变化

6 等待老的master复活成为新master的slave

# 1 哨兵是为了保证redis'服务的高可用,一个master挂掉,服务依然可以用
# 2 哨兵搭建步骤
  -1 先做一主两从
        6379是主mastre 
        6380是从slave
        6381是从slave
  -2 启用哨兵(哨兵是一个redis进程,哨兵sentinel进程可以分别放在不同的机器上)
    ## 配置解释:
sentinel monitor <master-name> <ip> <redis-port> <quorum>
告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效
sentinel auth-pass <master-name> <password>
设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
sentinel down-after-milliseconds <master-name> <milliseconds> 
这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒
sentinel parallel-syncs <master-name> <numslaves> 
这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
sentinel failover-timeout <master-name> <milliseconds>
failover-timeout 可以用在以下这些方面:     
1. 同一个sentinel对同一个master两次failover之间的间隔时间。   
2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。    
3.当想要取消一个正在进行的failover所需要的时间。    
4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了。

    # vim sentinel_26379.conf #创建一个sentinel的配置文件
      #26379端口--一个哨兵
    配置文件:
    port 26379
    daemonize yes# 是否以守护进程的形式来跑
    dir data# 数据存放目录
    protected-mode no#保护模式,写不写都行,现在不需要远程连它
    bind 0.0.0.0#绑定
    logfile "redis_sentinel.log"#日志存放路径,在数据存放路径下面
    sentinel monitor mymaster 127.0.0.1 6379 2#mymaster名字随便命 主master地址端口号 2代表要有两个sntinel觉得你挂了,你才是挂了
    sentinel down-after-milliseconds mymaster 30000#指定需要多少时间,master被这个sentinel主管地认为不可用.单位是毫秒,默认为30秒
    sentinel parallel-syncs mymaster 1#设置failover主备切换时,多少slave同事对新master进行同步,数字越小,切换时间越长.注:在备份的slave不可用,设为1保证每次只有一个slave处于不能处理命令请求状态.默认为1
    sentinel failover-timeout mymaster 180000#同一个sentinel对同一个master两次failover失败之间的事件间隔,单位毫秒,用默认即可
    #26380端口--一个哨兵
       port 26380
       daemonize yes
    dir data1
    protected-mode no
    bind 0.0.0.0
    logfile "redis_sentinel.log"
    sentinel monitor mymaster 127.0.0.1 6379 2
    sentinel down-after-milliseconds mymaster 30000
    sentinel parallel-syncs mymaster 1
    sentinel failover-timeout mymaster 180000
    #26381端口--一个哨兵
    port 26381
    daemonize yes
    dir data2
    protected-mode no
    bind 0.0.0.0
    logfile "redis_sentinel.log"
    sentinel monitor mymaster 127.0.0.1 6379 2
    sentinel down-after-milliseconds mymaster 30000
    sentinel parallel-syncs mymaster 1
    sentinel failover-timeout mymaster 180000
    
    
    -redis-sentinel 配置文件来启动哨兵
    -启动哨兵:
    redis-sentinel 配置文件
    # ./src/redis-sentinel sentinel_26379.conf # 命令在src路径下
    redis-sentinel sentinel_26379.conf
    redis-sentinel sentinel_26380.conf
    redis-sentinel sentinel_26381.conf
    # ps aux |grep redis # 查看当前redis-sentinel进程
    
    -从客户端登录到一个哨兵上
    redis-cli -p 26379 # 哨兵不能写数据
    -输入info
    最后一行看到
    master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3
    # 显示主数据库地址端口,从数据库数量,几个哨兵
    -把主库手动停掉
    shutdown
    
    -连到哨兵上,输入info(主master自动变成了6381)
  master0:name=mymaster,status=ok,address=101.133.225.166:6381,slaves=4,sentinels=3#这是视频结果,有问题
  master0:name=mymaster,status=ok,address=127.0.0.1:6381,slaves=2,sentinels=3#这是我的正常结果,6381变为主。从库还是有2,实际有一个已经被关闭了
        
    -原来的主库如果启动,主库会变为从库,继续运行redis服务(哨兵不能重启redis服务,只能监控)(视频碰到了问题:数据脏了)
    
    
# python客户端连接(直接连了主库,主库挂掉,不能改代码吧)
import redis
from redis.sentinel import Sentinel

# 连接哨兵服务器(主机名也可以用域名)
# 10.0.0.101:26379
sentinel = Sentinel([('10.0.0.101', 26379),
                     ('10.0.0.101', 26378),
                     ('10.0.0.101', 26377)
             ],socket_timeout=5)
print(sentinel)
# 获取主服务器地址
master = sentinel.discover_master('mymaster')
print(master)


# 获取从服务器地址
slave = sentinel.discover_slaves('mymaster')
print(slave)


# 获取主服务器进行写入
# master = sentinel.master_for('mymaster', socket_timeout=0.5)
# w_ret = master.set('foo', 'bar')
#
#
# slave = sentinel.slave_for('mymaster', socket_timeout=0.5)
# r_ret = slave.get('foo')
# print(r_ret)

 

相关文章: