当前位置: 首页 > news >正文

Redis从入门到精通(二)

八、三种特殊数据类型

8.1、geospatial 地理位置

Redis的Geo可以推算地理位置的信息

只有6个命令:

  • geoadd:添加地理位置的坐标。
  • geopos:获取地理位置的坐标。
  • geodist:计算两个位置之间的距离。
  • georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。
  • georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。
  • geohash:返回一个或多个位置对象的 geohash 值。

geoadd 用于存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。

geoadd 语法格式如下:

GEOADD key  latitude longitude member [latitude longitude member ...]

geoadd:添加地理位置的坐标。

127.0.0.1:6379> GEOADD china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> GEOADD china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> GEOADD china:city 113.28 23.12 guangzhou
(integer) 1
127.0.0.1:6379> GEOADD china:city 113.66 34.75 henan
(integer) 1

geopos:获取地理位置的坐标。

127.0.0.1:6379> GEOPOS china:city beijing  # 获取指定城市的精度和纬度
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
127.0.0.1:6379> GEOPOS china:city henan
1) 1) "113.65999907255172729"
   2) "34.74999926510690784"
127.0.0.1:6379> 

geodist:计算两个位置之间的距离。

geodist 用于返回两个给定位置之间的距离。

geodist 语法格式如下:

GEODIST key member1 member2 [m|km|ft|mi]

member1 member2 为两个地理位置。

最后一个距离单位参数说明:

  • m :米,默认单位。
  • km :千米。
  • mi :英里。
  • ft :英尺。
127.0.0.1:6379> GEODIST china:city beijing henan km # 查看北京到河南的距离
"621.8822"
127.0.0.1:6379> GEODIST china:city beijing shanghai km # 查看北京到上海的距离
"1067.3788"
127.0.0.1:6379> 

georadius、georadiusbymember

  • georadius 以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。

  • georadiusbymember 和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 georadiusbymember 的中心点是由给定的位置元素决定的, 而不是使用经度和纬度来决定中心点。

  • georadius 与 georadiusbymember 语法格式如下:

  • GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
    GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
    
  • 参数说明:

    • m :米,默认单位。
    • km :千米。
    • mi :英里。
    • ft :英尺。
    • WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。
    • WITHCOORD: 将位置元素的经度和纬度也一并返回。
    • WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。
    • COUNT 限定返回的记录数。
    • ASC: 查找结果根据距离从近到远排序。
    • DESC: 查找结果根据从远到近排序
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km # 以110,30这个经纬度为中心,寻找方圆1000KM你的城市
1) "guangzhou"
2) "henan"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withdist # 显示到中心距离的位置
1) 1) "guangzhou"
   2) "831.7713"
2) 1) "henan"
   2) "630.2160"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withcoord # 显示他人的定位信息
1) 1) "guangzhou"
   2) 1) "113.27999979257583618"
      2) "23.1199990030198208"
2) 1) "henan"
   2) 1) "113.65999907255172729"
      2) "34.74999926510690784"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withdist withcoord count 1 # 筛选出指定的结果 
1) 1) "henan"
   2) "630.2160"
   3) 1) "113.65999907255172729"
      2) "34.74999926510690784" 
# 找出位于指定元素周围的其他元素
127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1000 km 
1) "henan" 
2) "beijing"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city shanghai 1000 km 
1) "shanghai"
2) "henan"

8.2、Hyperloglog

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

什么是基数?

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

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

序号命令及描述
1[PFADD key element element …] 添加指定元素到 HyperLogLog 中。
2[PFCOUNT key key …] 返回给定 HyperLogLog 的基数估算值。
3[PFMERGE destkey sourcekey sourcekey …] 将多个 HyperLogLog 合并为一个 HyperLogLog
127.0.0.1:6379> PFADD runoobkey "redis" "mongodb" "mysql" # 创建第一组元素
(integer) 1
127.0.0.1:6379> PFCOUNT runoobkey # 统计runoobkey 元素的基数数量
(integer) 3
127.0.0.1:6379> PFADD myset "redis" "mysql" "java" # 创建第二组 myset
(integer) 1 
127.0.0.1:6379> PFMERGE mykey myset runoobkey # 合并两组
OK
127.0.0.1:6379> PFCOUNT mykey
(integer) 4

8.3、Bitmaps

使用bitmaps来记录一周的打卡
查看某天是否打卡

127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 1
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 0
(integer) 0
127.0.0.1:6379> getbit sign 3
(integer) 1
127.0.0.1:6379> getbit sign 6
(integer) 0

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

127.0.0.1:6379> bitcount sign  # 统计这周打卡的天数
(integer) 3

九、事务

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

一次性、顺序性、排他性!

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

  • 开始事务。(MULTI)
  • 命令入队。
  • 执行事务。(EXEC)

Redis事务没有隔离级别的概念

Redis单条命令保证原子性,但事务不保证原子性

Redis 事务命令

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

序号命令及描述
1DISCARD 取消事务,放弃执行事务块内的所有命令。
2EXEC 执行所有事务块内的命令。
3MULTI 标记一个事务块的开始。
4UNWATCH 取消 WATCH 命令对所有 key 的监视。
5[WATCH key key …] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
127.0.0.1:6379> MULTI  # 开启事务
OK
# 命令入队
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> get k2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> EXEC # 执行事务
1) OK
2) OK
3) "v2"
4) OK

放弃事务

127.0.0.1:6379>  MULTI # 开启事务
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> DISCARD #放弃事务
OK
127.0.0.1:6379> get k4 # 事务中的所有命令都不会被执行
(nil)

编译型异常(代码有问题,命令有错)事务中所有的命令都不会被执行

127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379(TX)> set k1 v1 
QUEUED
127.0.0.1:6379(TX)> set k2 v2 
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> getset k3
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> EXEC # 执行事务报错
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k4 # 所有命令都不会被执行
(nil)

运行时异常!如果事务队列中存在与发行错误,那么执行命令的时候,其他命令可以执行,错误命令抛出异常

127.0.0.1:6379> set k1 "hello"
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> INCR k1
QUEUED
127.0.0.1:6379(TX)> set k2 v2 
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> get k3
QUEUED
127.0.0.1:6379(TX)> EXEC
1) (error) ERR value is not an integer or out of range
2) OK
3) OK
4) "v3"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379> get k3
"v3"

监控!

# Redis监控测试
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money # 监视 money 对象
OK
127.0.0.1:6379> MULTI  # 事务正常结束,数据期间米有发生变动就正常执行成功
OK
127.0.0.1:6379(TX)> DECRBY money 20
QUEUED
127.0.0.1:6379(TX)> INCRBY out 20
QUEUED
127.0.0.1:6379(TX)> EXEC
1) (integer) 80
2) (integer) 20

十、Redis配置文件详解

10.1、配置文件unit单位对大小写不敏感!

网络

bind 127.0.0.1 -::1  		# 绑定的IP
protected-mode yes 			# 保护模式
port 6379					# 默认端口号

通用GENERAL

daemonize yes 						# 以守护进程的方式运行,默认是no,我们需要修改为yes
pidfile /var/run/redis_6379.pid		# 如果以后台方式运行,我们就需要指定一个pid文件

# 日志
# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice
logfile "" # 日志的文件位置名
databases 16 # 数据库的数量,默认16个数据库
always-show-logo no		# 是否总显示LOGO

快照

持久化,在规定的时间内,执行了多少次操作,则会持久化到文件 .rdb .aof

redis 是内存数据库,如果没有持久化,那么数据断电即失!

# 如果3600秒内,如果至少有一个key进行了修改,我们就会进行持久化操作
save 3600 1
# 如果300秒内,如果至少有100个key进行了修改,我们就会进行持久化操作
save 300 100
# 如果60秒内,如果至少有10000个key进行了修改,我们就会进行持久化操作
save 60 10000
# 我们后续会定义自己的测试

stop-writes-on-bgsave-error yes		# 持久化如果出错,是否继续工作

rdbcompression yes					# 是否压缩rdb文件,需要消耗一些CPU的资源

rdbchecksum yes						# 保存rdb文件的时候,进行错误的检查校验

dir ./								# rdb文件保存的目录

SECURITY 安全

设置密码

127.0.0.1:6379> CONFIG GET requirepass 		#获取redis的密码
1) "requirepass"
2) ""
127.0.0.1:6379> CONFIG SET requirepass "zjch1328"	# 设置redis的密码
OK
127.0.0.1:6379> CONFIG GET requirepass
1) "requirepass"
2) "zjch1328"
127.0.0.1:6379> CONFIG GET requirepass
(error) NOAUTH Authentication required.
127.0.0.1:6379> AUTH zjch1328		# 使用密码进行登录
OK

CLIENTS 客户端

maxclients 10000		# 设置能连接上redis的最大客户端的数量
maxmemory <bytes>		# redis 配置最大的内存容量
maxmemory-policy noeviction		# 内存到达上限之后的处理策略
1、volatile-lru:只对设置了过期时间的key进行LRU(默认值) 
2、allkeys-lru : 删除lru算法的key   
3、volatile-random:随机删除即将过期key   
4、allkeys-random:随机删除   
5、volatile-ttl : 删除即将过期的   
6、noeviction : 永不过期,返回错误

APPEND ONLY aof模式

appendonly no 		# 默认是不开启aof模式的
appendfilename "appendonly.aof" 	# 持久化的文件的名字

# appendfsync always	# 每次修改都会写入 sync
appendfsync everysec	# 美妙执行一次 sync,可能会丢失着一秒的数据
# appendfsync no		# 不执行 sync,这个时候操作系统自己同步数据,速度最快

10.2、网络相关的配置

  • bind 默认情况 bind=127.0.0.1 只能接受本机的访问请求 注释掉bind=127.0.0.1
  • 不写的情况下,无限制接受任何IP地址访问,生产环境肯定要写你的应用服务器的地址;服务器是需要远程访问的,所以要将其注释掉。
  • protected-mode 开启之后,也只能本地链接 把protected-mode no
  • tcp-backlog 设置tcp的backlog,backlog其实是一个链接队列,backlog队列=未完成三次握手的队列+王城三次握手的队列。在高并发下你需要一个高的backlog值来避免慢客户端的问题
  • timeout 设置连接无操作超时时间

十一、Jedis

测试

1、导入对应的依赖

<dependencies>
        <!--导入jedis的依赖包-->
        <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.7.0</version>
        </dependency>
        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.79</version>
        </dependency>
</dependencies>

2、编码测试

  • 连接数据库
  • 操作命令
  • 断开连接
public class TestPing {
    public static void main(String[] args) {
        // 1、new Jedis()对象即可
        Jedis jedis = new Jedis("***.***.***.***",6379);
        // jedis 所有命令就是之前的所有指令
        jedis.auth("*******");
        System.out.println(jedis.ping());
    }
}

IDEA上连接jedis时报错:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

解决:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.25</version>
</dependency>
查看端口开放信息,如果没看见 6379,就需要设置
firewall-cmd --list-ports

开启 6379 端口
firewall-cmd --zone=public --add-port=6379/tcp --permanent

最后记得重载防火墙生效
重载:firewall-cmd --reload

相关文章:

  • 2021.09青少年软件编程(Python)等级考试试卷(四级)
  • JAVA计算机毕业设计毕业论文管理系统Mybatis+系统+数据库+调试部署
  • Redis实战 - 01 Redis 和 SpringSecurity Oauth2 实现认证授权中心
  • 数据结构:堆
  • 基于机器学习的搜索推荐系统
  • MATLAB | 分段赋色折线图及其图例绘制
  • C#面向对象程序设计课程实验三:实验名称:C#数组和集合
  • 数据结构--(栈、队列实现及3个OJ题)
  • 实时数据同步工具<Maxwell 操作案例>
  • 【设计模式】-创建型模式-第2章第3讲-【建造者模式】
  • CS231n Module2: CNN part1:Architecture
  • 模电学习1. 三极管基础知识及常用电路
  • 优化APK体积
  • 【初学者入门C语言】之函数(八)
  • 《Linux基本常识的介绍》
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 5、React组件事件详解
  • Android开源项目规范总结
  • Angular数据绑定机制
  • Fabric架构演变之路
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JavaScript设计模式之工厂模式
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • vue 个人积累(使用工具,组件)
  • vuex 笔记整理
  • 记一次删除Git记录中的大文件的过程
  • 七牛云假注销小指南
  • 巧用 TypeScript (一)
  • 驱动程序原理
  • 深度学习入门:10门免费线上课程推荐
  • 用Python写一份独特的元宵节祝福
  • 走向全栈之MongoDB的使用
  • 最简单的无缝轮播
  • Python 之网络式编程
  • 翻译 | The Principles of OOD 面向对象设计原则
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​Linux·i2c驱动架构​
  • #Z2294. 打印树的直径
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (4.10~4.16)
  • (Git) gitignore基础使用
  • (Java数据结构)ArrayList
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (强烈推荐)移动端音视频从零到上手(上)
  • (一)基于IDEA的JAVA基础10
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .Net 代码性能 - (1)
  • .net中的Queue和Stack
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • @property括号内属性讲解