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

redis类型解析汇总

redis类型解析汇总

  • 介绍
  • 数据类型简介
    • 主要数据类型:
    • 衍生类型:
  • 字符串(String)
    • 底层设计原理
    • 图例
    • 设计优势
    • 字符串使用方法
      • 设置字符串值
      • 获取字符串值
      • 获取和设置部分字符串
      • 获取字符串长度
      • 追加字符串
      • 设置新值并返回旧值
      • 递增/递减
      • 同时设置多个键值对
      • 同时获取多个键的值
      • 设置字符串值并带有过期时间
      • 自增字符串值为浮点数
  • 哈希(Hash)
    • 底层设计原理
      • 哈希表
      • 哈希冲突解决方法
    • 图例
    • 哈希使用方法
      • 设置指定key
      • 获取指定key
      • 删除指定key
      • 获取指定key字段数量
      • 获取指定key中所有字段
      • 获取指定key对应所有值
      • 获取指定key对应所有字段和值
      • 若field不存在时设置
      • 批量设置
      • 对指定key中指定字段值增加数值(int值)
      • 字段判空
      • 迭代指定key
      • 获取指定key指定字段值长度
      • 批量返回指定key值的字段值
      • 对指定key中指定字段值增加数值(float值)
      • 若field不存在时设置(存在NX/XX参数时)
      • 批量移除字段的TTL
  • 列表(List)
    • 底层设计原理
    • 图例
    • 列表使用方法
      • 列表头插
      • 列表尾插
      • 移除头部元素
      • 移除尾部元素
      • 获取指定索引元素
      • 获取列表长度
      • 获取指定范围元素
      • 移除指定数量元素
      • 设置指定索引元素
      • 裁剪指定范围元素
      • 阻塞模式头移
      • 阻塞模式尾移
      • 指定元素位置插入元素
  • 集合(Set)
    • 底层设计原理
    • 图例
    • 集合使用方法
      • 添加成员
      • 移除成员
      • 获取所有成员
      • 检查是否为集合成员
      • 获取集合元素数量
      • 获取移除的成员
      • 获取指定数量成员
      • 转移集合成员
      • 返回集合交集
      • 获取集合并集
      • 获取集合差集
      • 计算并保存集合交集
      • 计算并保存集合并集
      • 计算并保存集合差集
  • 有序集合(Sorted Set)
    • 底层设计原理
      • 跳跃表(Skip List)
      • 哈希表(Hash Table)
    • 图例
    • 有序集合使用方法
      • 添加成员
      • 删除成员
      • 查询成员个数
      • 查询成员的分数
      • 按排名查询成员
      • 按分数范围查询成员
      • 按分数范围删除成员
      • 增加成员的分数
      • 查看排名范围内的成员和分数
      • 逆序按排名查询成员
      • 逆序按分数范围查询成员
      • 删除排名范围内的成员
      • 获取有序集合中在字典范围内成员数量
      • 按字典范围查询成员
      • 按字典范围删除成员
      • 求集合的并集
      • 求集合的交集
      • 求集合的并集和
  • 位图(BitMap)
    • 底层设计原理
    • 应用场景
    • 图例
    • 位图使用方法
      • 设置位图中的位
      • 获取位图中的位
      • 获取位图的长度
      • 求位图之间的逻辑操作
      • 设置位图的长度
      • 获取位图指定范围内的所有位
      • 设置位图指定范围内的所有位
      • 获取位图指定范围内的所有位,并对它们进行位运算
  • 超级日志结构(HyperLogLog)
    • 底层设计原理
    • 应用场景
    • 图例
    • HyperLogLog使用方法
      • 添加元素到HyperLogLog
      • 获取HyperLogLog的基数估计
      • 合并多个HyperLogLog
    • 其他说明
    • 注意事项
  • 地理位置(GeoSpatial)
    • 底层设计原理
    • 应用场景
    • 图例
    • GeoSpatial使用方法
      • 添加地理位置及其经纬度信息
      • 计算两个地理位置之间的距离
      • 获取地理位置的Geohash值
      • 获取地理位置的经纬度信息
      • 根据指定地理位置查询范围内的其他地理位置
      • 根据指定的地理位置成员查询范围内的其他地理位置
      • 从节点上执行地理位置查询
      • 统计给定范围内的地理位置数量
      • 通过复杂的过滤器查询符合条件的地理位置
      • 执行GEOSEARCH查询并将结果存储到另一个GeoSpatial结构中
  • 流(Stream)
    • 底层设计原理
    • 应用场景
    • 图例
    • Stream使用方法
      • 创建Stream
      • 读取Stream
      • 消费者组管理
      • 获取Stream信息
      • 删除Stream中的条目
      • 使用示例
  • redis特性和优势
  • redis使用场景总结

介绍

Redis(Remote Dictionary Server 远程字典服务器)是一个开源的内存数据库,它可以作为缓存、数据库和消息中间件使用

数据类型简介

主要数据类型:

1. 字符串(String):

  • Redis 最基本的数据类型,可以存储文本、整数或者二进制数据。
  • 支持基本的字符串操作,如设置、获取、追加等。

2. 哈希(Hash):

  • 类似于关联数组,适合存储对象。
  • 每个哈希可以存储多个字段和对应的值。

3. 列表(List):

  • 链表结构,支持从两端压入和弹出元素,适合存储有序的元素集合。
  • 可以用于实现队列、栈等数据结构。

4. 集合(Set):

  • 无序且唯一的元素集合,支持集合间的基本操作(交集、并集等)。
  • 可以用于存储不重复的元素集合,如用户标签、好友列表等。

5. 有序集合(Sorted Set):

  • 类似于集合,但每个元素关联一个分数,支持按分数排序。
  • 可以用于实现排行榜、范围查询等功能。

衍生类型:

1. 位图(BitMap):

  • Redis 提供了位操作命令,可以将字符串作为位数组来使用,支持位的设置、获取、计数等操作。
  • 适用于存储布尔型数据或者进行一些位运算操作。

2. 超级日志结构(HyperLogLog):

  • 用于进行基数统计,估算集合中不重复元素的数量。
  • 提供了一系列的命令用于添加元素、统计基数、合并 HyperLogLog 等。

3. 地理位置(GeoSpatial):

  • 通过经纬度坐标来存储地理位置信息,并支持查询两点之间的距离、查找附近的位置等功能。
  • 适用于实现地理位置服务、附近搜索等功能。

4. 流(Stream):

  • Redis 5.0 引入的新数据类型,类似于日志结构,支持添加、读取、消费消息等操作。
  • 可以用于实现消息队列、事件日志等应用场景。

字符串(String)

底层设计原理

在 Redis 中,字符串的底层结构是简单动态字符串(Simple Dynamic String,SDS)。SDS 是 Redis自己实现的一种字符串表示方式,相比于传统的 C 语言字符串,它具有以下优势,从而使得 Redis 中字符串操作更加高效

图例

// TODO 待补充

设计优势

1. 动态扩展:SDS 可以根据需要动态扩展字符串的长度,而不需要像 C 字符串那样每次都重新分配内存和拷贝数据,这样可以避免频繁的内存分配和释放,提高了性能。
2. 减少缓冲区溢出:SDS 在字符串末尾会额外存储一个字节的空间,用于存放空字符(‘\0’),这样即使字符串长度增加,也不会发生缓冲区溢出,提高了安全性。
3. 快速获取长度:SDS 结构中记录了字符串的长度信息,因此获取字符串长度的操作是 O(1) 的时间复杂度,而不像 C 字符串需要遍历整个字符串。
4. 二进制安全:SDS 可以存储任意二进制数据,而不仅限于文本数据,这使得 Redis 的字符串类型可以应对更多的应用场景,例如存储图片、序列化对象等。
5. 支持部分修改:SDS 支持在 O(1) 的时间复杂度内进行部分字符串的修改,比如替换某个位置的字符,这在某些应用场景下非常高效。

字符串使用方法

设置字符串值

  • SET key value [EX seconds] [PX milliseconds] [NX|XX]
    • 将字符串键 key 的值设置为 value。可以设置过期时间 EX seconds 或 PX milliseconds。
    • NX:仅在键不存在时设置值。
    • XX:仅在键已存在时设置值。
SET mykey "Hello"
SET mycounter 100 EX 3600 NX

获取字符串值

  • GET key
    • 获取键 key 的值。
GET mykey

获取和设置部分字符串

  • GETRANGE key start end

    • 返回键 key 中字符串值的子字符串,从 start 到 end 的位置(包括两端)。
  • SETRANGE key offset value

    • 用指定的 value 替换键 key 中字符串的部分内容,从 offset 开始。
GETRANGE mykey 0 3  # 返回 "Hell"
SETRANGE mykey 6 "Redis"  # 将 mykey 中索引为 6 开始的部分替换为 "Redis"

获取字符串长度

  • STRLEN key
    • 返回键 key 中字符串值的长度。
STRLEN mykey

追加字符串

  • APPEND key value
    • 将 value 追加到键 key 当前值的末尾,并返回新的字符串长度。
APPEND mykey ", welcome to Redis!"

设置新值并返回旧值

  • GETSET key value
    • 将键 key 的值设置为 value,并返回旧值。
GETSET mykey "New Value"

递增/递减

  • INCR key
    • 将键 key 中存储的数字值增加 1。
  • DECR key
    • 将键 key 中存储的数字值减少 1。
  • INCRBY key increment
    • 将键 key 中存储的数字值增加指定的 increment。
  • DECRBY key decrement
    • 将键 key 中存储的数字值减少指定的 decrement。
INCR mycounter
DECR mycounter
INCRBY mycounter 10
DECRBY mycounter 5

假设我们有一个键 mykey,它最初存储的值是 “Hello”。

同时设置多个键值对

  • MSET key1 value1 [key2 value2 …]
    • 同时设置多个键值对。
MSET key1 "value1" key2 "value2"

同时获取多个键的值

  • MGET key1 [key2 …]
    • 同时获取多个键的值。
MGET key1 key2

设置字符串值并带有过期时间

  • SETEX key seconds value
    • 设置键 key 的值为 value,并设置过期时间为 seconds 秒。
SETEX mykey 60 "Hello"  # 设置 mykey 的值为 "Hello",并设置过期时间为 60

自增字符串值为浮点数

  • INCRBYFLOAT key increment
    • 将键 key 中存储的数字值增加指定的浮点数 increment。
SET myfloat 10.5     
INCRBYFLOAT myfloat 0.1  # 将 myfloat 的值增加 0.1     

哈希(Hash)

底层设计原理

其实现主要包括两个部分:哈希表(Hash table)和哈希冲突解决方法(Collision resolution)

哈希表

Redis 中的哈希表实际上是一个数组(Array),数组的每个元素称为一个哈希桶(bucket)。每个桶中可以存储多个哈希节点(Hash node),每个节点包含一个键值对。

  • 数组大小和桶的数量: Redis 在创建哈希表时会预先分配一定大小的数组,数组的每个元素是一个桶。数组的大小会动态调整,以适应哈希表中存储的键值对数量变化。
  • 桶的选择: Redis 使用键的哈希值通过取模运算来决定存储在哪个桶中,例如 hash(key) % buckets_count。这样可以快速定位到存储和检索数据的位置

哈希冲突解决方法

当两个不同的键通过哈希函数计算得到相同的索引位置时,就会发生哈希冲突。Redis 使用链地址法(Separate chaining)来解决哈希冲突:

  • 链表存储: 每个桶中存储一个链表或者其他类似的数据结构(例如跳表),用于存放哈希冲突的键值对。这样即使发生冲突,也能通过遍历链表或者其他数据结构找到正确的键值对

图例

// TODO 待补充

哈希使用方法

设置指定key

  1. HSET key field value
  • 设置哈希 key 中的字段 field 的值为 value。
HSET user:1001 username "alice"

获取指定key

  1. HGET key field
  • 获取哈希 key 中字段 field 的值。
HGET user:1001 username

删除指定key

  1. HDEL key field [field …]
  • 删除哈希 key 中的一个或多个字段。
HDEL user:1001 username

获取指定key字段数量

  1. HLEN key
  • 返回哈希 key 中字段的数量。
HLEN user:1001

获取指定key中所有字段

  1. HKEYS key
  • 返回哈希 key 中所有的字段。
HKEYS user:1001

获取指定key对应所有值

  1. HVALS key
  • 返回哈希 key 中所有的值。
HVALS user:1001

获取指定key对应所有字段和值

  1. HGETALL key
  • 返回哈希 key 中的所有字段和值。
HGETALL user:1001

假设有一个用户信息存储在哈希中:

127.0.0.1:6379> HSET user:1001 username "alice"
(integer) 1
127.0.0.1:6379> HSET user:1001 email "alice@example.com"
(integer) 1
127.0.0.1:6379> HSET user:1001 age "30"
(integer) 1

可以使用以上方法来操作这个哈希数据结构:

127.0.0.1:6379> HGET user:1001 username
"alice"
127.0.0.1:6379> HGETALL user:1001
1) "username"
2) "alice"
3) "email"
4) "alice@example.com"
5) "age"
6) "30"
127.0.0.1:6379> HDEL user:1001 age
(integer) 1
127.0.0.1:6379> HLEN user:1001
(integer) 2
127.0.0.1:6379> HKEYS user:1001
1) "username"
2) "email"
127.0.0.1:6379> HVALS user:1001
1) "alice"
2) "alice@example.com"

若field不存在时设置

  1. HSETNX key field value
  • 当字段 field 不存在时,设置哈希 key 中的字段 field 的值为 value。
HSETNX user:1001 username "alice"

批量设置

  1. HMSET key field value [field value …]
  • 同时设置多个字段的值。
HMSET user:1001 username "alice" email "alice@example.com" age "30"

对指定key中指定字段值增加数值(int值)

  1. HINCRBY key field increment
  • 将哈希 key 中的字段 field 的值增加 increment。
HINCRBY user:1001 age 1

字段判空

  1. HEXISTS key field
  • 判断哈希 key 中是否存在字段 field。
HEXISTS user:1001 username

迭代指定key

  1. HSCAN key cursor [MATCH pattern] [COUNT count]
  • 迭代哈希 key 中的键值对。
HSCAN user:1001 0

获取指定key指定字段值长度

  1. HSTRLEN key field
  • 返回哈希 key 中字段 field 的值的长度。
HSTRLEN user:1001 username

批量返回指定key值的字段值

  1. HMGET key field [field …]
  • 返回哈希 key 中一个或多个字段的值。
HMGET user:1001 username email

对指定key中指定字段值增加数值(float值)

  1. HINCRBYFLOAT key field increment
  • 将哈希 key 中的字段 field 的值增加 increment(浮点数)。
HINCRBYFLOAT user:1001 score 0.5

若field不存在时设置(存在NX/XX参数时)

  1. HSET key field value [NX|XX]
  • 当指定 NX 或 XX 参数时,只在字段不存在或者已存在时才设置值。
HSET user:1001 username "alice" NX

批量移除字段的TTL

  1. HPERSIST key field [field …]
  • 移除哈希 key 中一个或多个字段的生存时间(TTL)。
HPERSIST user:1001 username

列表(List)

底层设计原理

List数据结构是一个双向链表(双端链表)实现的,支持在列表的两端进行快速的插入(push)和删除(pop)操作。这种实现保证了在头部和尾部进行插入和删除的时间复杂度都是O(1)

图例

// TODO

列表使用方法

列表头插

  1. LPUSH key value [value …]
  • 将一个或多个值插入到列表头部。
LPUSH mylist "world"
LPUSH mylist "hello"

列表尾插

  1. RPUSH key value [value …]
  • 将一个或多个值插入到列表尾部。
RPUSH mylist "foo"
RPUSH mylist "bar"

移除头部元素

  1. LPOP key
  • 移除并返回列表头部的元素。
LPOP mylist

移除尾部元素

  1. RPOP key
  • 移除并返回列表尾部的元素。
RPOP mylist

获取指定索引元素

  1. LINDEX key index
  • 返回列表中指定索引位置的元素。
LINDEX mylist 0

获取列表长度

  1. LLEN key
  • 返回列表的长度。
LLEN mylist

获取指定范围元素

  1. LRANGE key start stop
  • 返回列表中指定范围内的元素。
LRANGE mylist 0 2

移除指定数量元素

  1. LREM key count value
  • 移除列表中指定数量的元素。
LREM mylist 2 "hello"

设置指定索引元素

  1. LSET key index value
  • 设置列表中指定索引位置的元素值。
LSET mylist 1 "new_value"

裁剪指定范围元素

  1. LTRIM key start stop
  • 对列表进行裁剪,保留指定范围内的元素。
LTRIM mylist 0 2

阻塞模式头移

  1. BLPOP key [key …] timeout
  • 从列表头部弹出元素,如果列表为空则阻塞并等待元素的到来。
BLPOP mylist 10

阻塞模式尾移

  1. BRPOP key [key …] timeout
  • 从列表尾部弹出元素,如果列表为空则阻塞并等待元素的到来。
BRPOP mylist 10

指定元素位置插入元素

  1. LINSERT key BEFORE|AFTER pivot value
  • 在列表中指定元素 pivot 的前面或后面插入元素 value。
LINSERT mylist BEFORE "world" "new_value"

集合(Set)

底层设计原理

  • 每个集合成员(如 member1, member2, member3)被映射到哈希表的一个桶中。
  • 桶内的数据结构可以是链表或其他形式,用于处理哈希冲突,但每个键值对的键都是成员的值,值则是一个常量(NULL)。
  • Set 数据结构非常适合用于存储唯一值的场景,例如标签、用户 ID 等,并且能够通过交集、并集、差集等操作,支持更复杂的数据处理需求

图例

// TODO

集合使用方法

添加成员

  1. SADD key member [member …]
  • 向集合添加一个或多个成员。
SADD myset "member1"
SADD myset "member2"

移除成员

  1. SREM key member [member …]
  • 从集合中移除一个或多个成员。
SREM myset "member1"

获取所有成员

  1. SMEMBERS key
  • 返回集合中的所有成员。
SMEMBERS myset

检查是否为集合成员

  1. SISMEMBER key member
  • 检查 member 是否是集合 key 的成员。
SISMEMBER myset "member1"

获取集合元素数量

  1. SCARD key
  • 返回集合的基数(集合中元素的数量)。
SCARD myset

获取移除的成员

  1. SPOP key [count]
  • 移除并返回集合中的一个或多个随机元素。
SPOP myset

获取指定数量成员

  1. SRANDMEMBER key [count]
  • 返回集合中一个或多个随机元素(不移除元素)。
SRANDMEMBER myset 2

转移集合成员

  1. SMOVE source destination member
  • 将 member 从 source 集合移动到 destination 集合。
SMOVE myset myotherset "member1"

返回集合交集

  1. SINTER key [key …]
  • 返回多个集合的交集。
SINTER myset myotherset

获取集合并集

  1. SUNION key [key …]
  • 返回多个集合的并集。
SUNION myset myotherset

获取集合差集

  1. SDIFF key [key …]
  • 返回多个集合的差集。
SDIFF myset myotherset

计算并保存集合交集

  1. SINTERSTORE destination key [key …]
  • 计算多个集合的交集,并将结果存储到新的集合中。
SINTERSTORE newset myset1 myset2

计算并保存集合并集

  1. SUNIONSTORE destination key [key …]
  • 计算多个集合的并集,并将结果存储到新的集合中。
SUNIONSTORE newset myset1 myset2

计算并保存集合差集

  1. SDIFFSTORE destination key [key …]
  • 计算多个集合的差集,并将结果存储到新的集合中。
SDIFFSTORE newset myset1 myset2

有序集合(Sorted Set)

底层设计原理

有序集合是一种特殊的数据结构,它类似于集合(Set),但每个成员都关联了一个分数(score),该分数用于对成员进行排序。有序集合的底层设计原理主要涉及两个核心点:跳跃表(SkipList)和哈希表(Hash Table)。

跳跃表(Skip List)

跳跃表是一种数据结构,用于在有序元素的集合中快速查找某个元素。它通过层级结构来实现快速查找,每一层都是元素的一个有序子集,最底层包含所有元素。在跳跃表中,每个节点包含一个指向下一个节点的指针,以及一个指向同一层下一个节点的指针。
在Redis中,有序集合的底层实现就是通过跳跃表来实现的。每个成员在跳跃表中都是一个节点,节点中包含了成员本身的值和分数,以及指向下一个节点和下一层节点的指针。通过跳跃表,Redis可以实现有序集合的快速查找和排序功能。

哈希表(Hash Table)

除了跳跃表,有序集合在底层还使用了哈希表来存储成员和分数之间的映射关系。哈希表是一种以键值对形式存储数据的数据结构,可以快速查找和访问数据。
在Redis中,有序集合使用哈希表来存储成员和分数之间的映射关系,这样可以在跳跃表中快速定位到某个成员的节点,然后通过哈希表找到成员对应的分数。哈希表的使用使得在有序集合中查找某个成员的分数变得高效。

图例

// TODO

有序集合使用方法

添加成员

  1. ZADD key score member [score member …]
  • 将一个或多个成员及其对应的分数添加到有序集合中。
ZADD myset 1 "member1" 2 "member2"

删除成员

  1. ZREM key member [member …]
  • 从有序集合中删除一个或多个成员。
ZREM myset "member1"

查询成员个数

  1. ZCARD key
  • 获取有序集合中成员的数量。
ZCARD myset

查询成员的分数

  1. ZSCORE key member
  • 获取指定成员的分数。
ZSCORE myset "member1"

按排名查询成员

  1. ZRANK key member
  • 获取指定成员在有序集合中的排名(从0开始)。
ZRANK myset "member1"

按分数范围查询成员

  1. ZRANGE key start stop [WITHSCORES]
  • 按分数从小到大的顺序,获取指定范围内的成员。
ZRANGE myset 0 1 WITHSCORES

按分数范围删除成员

  1. ZREMRANGEBYSCORE key min max
  • 删除分数在指定范围内的成员。
ZREMRANGEBYSCORE myset 0 5

增加成员的分数

  1. ZINCRBY key increment member
  • 给指定成员的分数增加增量increment。
ZINCRBY myset 2 "member1"

查看排名范围内的成员和分数

  1. ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
  • 按分数范围获取成员及其分数,支持分页。
ZRANGEBYSCORE myset 0 10 WITHSCORES LIMIT 0 2

逆序按排名查询成员

  1. ZREVRANK key member
  • 获取指定成员在有序集合中的逆序排名(从0开始)。
ZREVRANK myset "member1"

逆序按分数范围查询成员

  1. ZREVRANGE key start stop [WITHSCORES]
  • 按分数从大到小的顺序,获取指定范围内的成员。
ZREVRANGE myset 0 1 WITHSCORES

删除排名范围内的成员

  1. ZREMRANGEBYRANK key start stop
  • 删除排名在指定范围内的成员。
ZREMRANGEBYRANK myset 0 1

获取有序集合中在字典范围内成员数量

  1. ZLEXCOUNT key min max
  • 获取有序集合中在字典范围内(字典区间使用"-“和”+"表示)的成员数量。
ZLEXCOUNT myset "-" "+"

按字典范围查询成员

  1. ZRANGEBYLEX key min max [LIMIT offset count]
  • 按字典范围获取成员。
ZRANGEBYLEX myset "-" "[m" LIMIT 0 2

按字典范围删除成员

  1. ZREMRANGEBYLEX key min max
  • 删除字典范围内的成员。
ZREMRANGEBYLEX myset "-" "[m"

求集合的并集

  1. ZUNIONSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]
  • 计算给定有序集合的并集,并将结果存储在新的有序集合中。
ZUNIONSTORE dest 2 set1 set2 WEIGHTS 1 2

求集合的交集

  1. ZINTERSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]
  • 计算给定有序集合的交集,并将结果存储在新的有序集合中。
ZINTERSTORE dest 2 set1 set2

求集合的并集和

  1. ZUNION key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]
  • 计算给定有序集合的并集,并返回结果集。
ZUNION 2 set1 set2 WEIGHTS 1 2

位图(BitMap)

底层设计原理

位图是一种特殊的数据结构,它实际上是一个特定长度的字符串,字符串中的每个比特位都可以被设置或清除。这种设计使得Redis的位图非常节省内存,特别适合于需要高效存储大量布尔类型数据的场景

1. 存储结构:

  • Redis的位图是一个由字符串实现的位数组,其中每个比特位可以代表一个状态(通常是0或1)。
  • 位图的长度由用户定义,在Redis中可以使用命令 SETBIT 来设置位图的长度,如果超过当前长度,Redis会自动扩展。

2. 位操作命令:

  • Redis提供了一系列位操作的命令,包括设置位、清除位、查看位的值等,这些操作都是针对位图中的单个比特位进行的。

3. 内存优化:

  • 位图采用了非常紧凑的存储方式,每个比特位只占用1位(0或1),因此在存储大量布尔类型数据时非常节省内存。

应用场景

1. 用户在线状态:

  • 可以用一个位图来表示用户的在线状态,每个用户对应位图中的一个比特位,该位在用户在线时置为1,离线时置为0。这样可以高效地查询多个用户的在线状态。

2. 统计数据:

  • 可以用位图来记录用户的操作行为或者事件发生情况,比如记录用户每天的登录情况、签到情况等。通过位操作命令,可以快速统计和分析这些数据。

3. 布隆过滤器(Bloom Filter):

  • 布隆过滤器是一种快速判断一个元素是否在集合中的数据结构。Redis的位图可以用来实现简单的布隆过滤器,通过多个不同的哈希函数在位图中设置对应的比特位,来判断一个元素可能存在于集合中(不准确,但是高效)。

图例

// TODO

位图使用方法

设置位图中的位

  1. SETBIT key offset value
  • 将位图key中偏移量为offset的位的值设置为value(0或1)。
SETBIT mybitmap 0 1   # 将mybitmap中偏移量为0的位设置为1

获取位图中的位

  1. GETBIT key offset
  • 获取位图key中偏移量为offset的位的值。
GETBIT mybitmap 0   # 获取mybitmap中偏移量为0的位的值

获取位图的长度

  1. BITCOUNT key [start end]
  • 统计位图key中值为1的位的数量。
BITCOUNT mybitmap   # 统计mybitmap中所有值为1的位的数量

求位图之间的逻辑操作

  1. BITOP operation destkey key [key …]
  • 对一个或多个位图执行位运算,并将结果保存到destkey中。operation可以是AND、OR、XOR、NOT等。
BITOP AND destbitmap mybitmap1 mybitmap2   # 将mybitmap1和mybitmap2按位进行AND操作,并将结果存储到destbitmap中

设置位图的长度

  1. BITFIELD key [GET type offset] [SET type offset value]
  • 对位图进行更加复杂的操作,可以用于获取和设置指定偏移量的位。
BITFIELD mybitmap GET u4 0   # 获取mybitmap中偏移量为04位无符号整数
BITFIELD mybitmap SET u4 0 10   # 设置mybitmap中偏移量为04位无符号整数为10

获取位图指定范围内的所有位

  1. BITFIELD key [GET type offset] [GET type offset] …
  • 可以一次性获取多个不同偏移量的位的值。
BITFIELD mybitmap GET u4 0 GET u4 4   # 获取mybitmap中偏移量044位无符号整数

设置位图指定范围内的所有位

  1. BITFIELD key [SET type offset value] [SET type offset value] …
  • 可以一次性设置多个不同偏移量的位的值。
BITFIELD mybitmap SET u4 0 10 SET u4 4 5   # 设置mybitmap中偏移量044位无符号整数分别为105

获取位图指定范围内的所有位,并对它们进行位运算

  1. BITFIELD key [GET type offset] [GET type offset] … [operation type] [operation value]
  • 可以在获取位的同时,对获取到的位进行位运算。
BITFIELD mybitmap GET u4 0 GET u4 4 OR 5   # 获取mybitmap中偏移量044位无符号整数,并对它们进行OR运算(假设5是一个值)

超级日志结构(HyperLogLog)

HyperLogLog(简称HLL)是一种用于近似计数的数据结构,主要用于解决集合的基数估计问题。它可以在极小的内存消耗下,对大型数据集合的基数进行估计

底层设计原理

1. 基数估计:

  • HyperLogLog利用一种概率性算法来估计集合的基数(即不重复元素的数量),它的基本原理是通过对数据进行哈希映射,统计哈希值前导0的个数来估计基数。

2. 哈希函数:

  • HyperLogLog使用一种特殊的哈希函数,将元素映射到一个固定长度的二进制字符串中。这个哈希函数的设计对结果的准确性有很大影响。

3. 桶与计数器:

  • HyperLogLog将哈希值分配到多个桶中,并在每个桶中维护一个计数器,用于记录对应桶中哈希值前导0的最大长度。

4. 合并计数器:

  • 当多个HyperLogLog数据结构需要合并时,采用的是取各个桶中计数器的最大值作为合并后的结果,这样可以保证合并后的结果不会低于原始数据结构的估计值。

应用场景

HyperLogLog在Redis中的应用场景包括但不限于:
1. 独立用户数量统计:

  • 可以用于统计网站或应用的独立访客数量,以便进行用户行为分析和精准营销。

2. 基数估计:

  • 可以用于统计大数据集合的基数,例如网页访问量、搜索关键词数量等。

3. 数据去重:

  • 可以用于判断数据集合中是否存在重复元素,帮助进行数据去重处理。

图例

// TODO

HyperLogLog使用方法

添加元素到HyperLogLog

  1. PFADD key element [element …]
  • 将一个或多个元素添加到HyperLogLog中。
PFADD myloglog user1 user2 user3   # 将user1, user2, user3添加到名为myloglog的HyperLogLog中

获取HyperLogLog的基数估计

  1. PFCOUNT key [key …]
  • 获取一个或多个HyperLogLog的基数估计值。
PFCOUNT myloglog   # 获取名为myloglog的HyperLogLog的基数估计值

合并多个HyperLogLog

  1. PFMERGE destkey sourcekey [sourcekey …]
  • 将多个HyperLogLog合并为一个,并将结果存储到destkey中。
PFMERGE mergedlog myloglog1 myloglog2   # 将myloglog1和myloglog2合并为一个HyperLogLog,并将结果存储到mergedlog中

其他说明

1. HyperLogLog与其他数据结构结合使用:

  • 可以将HyperLogLog的结果与其他数据结构(如Sorted Set或Hash)结合使用,以实现更复杂的统计和分析功能。

2. 内存消耗与精度权衡:

  • HyperLogLog通过牺牲一定的精度来换取极小的内存消耗,但在实际使用中,需要根据具体的应用场景权衡精度和内存消耗。

注意事项

1. 基数估计误差:

  • HyperLogLog在进行基数估计时存在一定的误差,这个误差通常在1-2%之间,但在合适的场景下可以接受。

2. 数据存储和备份:

  • 在使用HyperLogLog时,需要考虑数据的持久化存储和备份策略,以防止数据丢失或出现不一致情况。

3. 数据更新和删除:

  • HyperLogLog结构本身不支持删除单个元素或更新元素的操作,因此需要在设计时考虑如何处理数据的更新和删除需求。

地理位置(GeoSpatial)

GeoSpatial(地理空间)数据结构是一种用于存储地理位置坐标的数据结构,主要包括地理位置的经度和纬度信息。它提供了高效的空间查询和距离计算功能,适用于需要基于地理位置进行检索和分析的应用场景

底层设计原理

1. 数据存储:

  • GeoSpatial在Redis内部使用有序集合(Sorted Set)来存储地理位置信息。有序集合的成员是地理位置的名称或标识符,而分数(score)则是地理位置的经纬度信息。

2. 地理位置编码:

  • 地理位置的经纬度信息通过一种特定的编码方式存储在有序集合中,通常使用WGS84坐标系的经度和纬度作为分数。Redis使用的是双精度浮点数来表示经纬度。

3. 空间索引:

  • Redis使用基于Geohash的空间索引来加速地理位置的查询。Geohash是一种将地理位置编码为字符串的方法,具有天然的空间特性,相近的地理位置在Geohash编码上也会比较接近。

4. 距离计算:

  • GeoSpatial支持根据地理位置计算两点之间的距离,通常使用的是欧氏距离或球面距离(例如大圆距离)来度量地理空间的距离。

5. 查询优化:

  • Redis通过有序集合的分数范围查询功能,可以高效地进行地理位置范围内的查询,比如获取某个位置周围一定距离内的其他位置。

应用场景

1. 位置推荐与附近搜索:

  • 许多应用需要根据用户当前位置或指定地点,推荐附近的商家、服务或活动。使用GeoSpatial可以高效地找到某个地理位置附近的其他位置,比如附近的餐馆、酒店或公园。

2. 地理围栏与地理提醒:

  • 通过设置地理围栏(Geofence),可以监控用户是否进入或离开某个特定的地理区域。这在位置服务和地理提醒应用中非常有用,如出租车调度、安全警报系统等。

3. 路径规划与导航:

  • 根据多个地理位置点,可以进行路径规划和导航功能。例如,从起点到终点之间的最佳路线,或者找到途径特定地点的路线。

4. 地理统计分析:

  • 分析地理位置数据可以提供有价值的商业洞察,如不同地区的用户分布、热门区域的访问频率等。这对于市场营销、城市规划或资源分配有重要意义。

5. 地理位置的实时更新与管理:

  • 对于需要实时更新的场景,如共享经济平台(共享单车、共享汽车)、实时定位服务(快递追踪、司机位置追踪)等,GeoSpatial提供了高效的数据存储和查询能力。

6. 地理位置相关的社交网络功能:

  • 在社交网络中,根据用户的地理位置推荐附近的朋友、活动或社区,增强用户交互和社交体验。

图例

// TODO

GeoSpatial使用方法

添加地理位置及其经纬度信息

  1. GEOADD key longitude latitude member [longitude latitude member …]
  • key: GeoSpatial的键名。
  • longitude, latitude: 地理位置的经度和纬度。
  • member: 地理位置的名称或标识符。
GEOADD cities 116.405285 39.904989 Beijing 121.472644 31.231706 Shanghai

计算两个地理位置之间的距离

  1. GEODIST key member1 member2 [unit]
  • key: GeoSpatial的键名。
  • member1, member2: 要计算距离的两个地理位置的名称或标识符。
  • unit (可选): 距离单位,默认为m(米),可选km(千米)、mi(英里)、ft(英尺)。
GEODIST cities Beijing Shanghai km

获取地理位置的Geohash值

  1. GEOHASH key member [member …]
  • key: GeoSpatial的键名。
  • member: 要获取Geohash的地理位置的名称或标识符。
GEOHASH cities Beijing Shanghai

获取地理位置的经纬度信息

  1. GEOPOS key member [member …]
  • key: GeoSpatial的键名。
  • member: 要获取经纬度的地理位置的名称或标识符。
GEOPOS cities Beijing

根据指定地理位置查询范围内的其他地理位置

  1. GEORADIUS key longitude latitude radius unit [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
  • key: GeoSpatial的键名。
  • longitude, latitude: 中心点的经度和纬度。
  • radius: 查询半径。
  • unit: 单位,可以是m(米)、km(千米)、mi(英里)、ft(英尺)。
  • 可选参数包括WITHCOORD(返回地理位置的经纬度)、WITHDIST(返回与中心点的距离)、WITHHASH(返回地理位置的Geohash)、COUNT(返回结果的数量)、ASC|DESC(结果排序)、STORE(将结果存储到另一个GeoSpatial结构)等。
GEORADIUS cities 116.405285 39.904989 1000 km WITHDIST

根据指定的地理位置成员查询范围内的其他地理位置

  1. GEORADIUSBYMEMBER key member radius unit [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
    参数与GEORADIUS类似,不同之处在于使用成员名称而不是经纬度来指定中心点。
GEORADIUSBYMEMBER cities Beijing 1000 km WITHCOORD

从节点上执行地理位置查询

  1. 只读版本的GEORADIUS与GEORADIUSBYMEMBER用于在从节点上执行地理位置查询。
    示例应用
    假设有一个名为cities的GeoSpatial结构存储了几个城市的地理位置信息:
GEOADD cities 116.405285 39.904989 Beijing
GEOADD cities 121.472644 31.231706 Shanghai

可以通过以下示例展示如何使用各种操作:

# 计算北京和上海之间的距离
GEODIST cities Beijing Shanghai km# 获取北京的Geohash值
GEOHASH cities Beijing# 获取上海的经纬度信息
GEOPOS cities Shanghai# 查找距离北京1000公里范围内的其他城市及距离
GEORADIUS cities 116.405285 39.904989 1000 km WITHDIST

统计给定范围内的地理位置数量

  1. GEOCOUNT key longitude latitude radius unit
  • key: GeoSpatial的键名。
  • longitude, latitude: 中心点的经度和纬度。
  • radius: 统计范围的半径。
  • unit: 单位,可以是m(米)、km(千米)、mi(英里)、ft(英尺)。
GEOCOUNT cities 116.405285 39.904989 1000 km

通过复杂的过滤器查询符合条件的地理位置

  1. GEOSEARCH key [FROMMEMBER member] [FROMLONLAT longitude latitude] [BYRADIUS radius unit] [BYBOX width height unit] [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
  • key: GeoSpatial的键名。
  • 可选参数包括从成员开始、从经纬度开始、通过半径、通过矩形框、返回经纬度、返回距离、返回Geohash、结果数量、排序、存储等。
GEOSEARCH cities BYRADIUS 1000 km FROMMEMBER Beijing WITHDIST

执行GEOSEARCH查询并将结果存储到另一个GeoSpatial结构中

  1. GEOSEARCHSTORE destkey [key] [FROMMEMBER member] [FROMLONLAT longitude latitude] [BYRADIUS radius unit] [BYBOX width height unit] [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]
  • destkey: 存储结果的目标GeoSpatial的键名。
  • 其他参数与GEOSEARCH类似。
    GEOSEARCHSTORE result_cities BYRADIUS 1000 km FROMMEMBER Beijing WITHCOORD
    应用示例
    假设继续使用名为cities的GeoSpatial结构:
GEOADD cities 116.405285 39.904989 Beijing
GEOADD cities 121.472644 31.231706 Shanghai

展示如何使用这些新命令:

# 统计距离北京1000公里范围内的城市数量
GEOCOUNT cities 116.405285 39.904989 1000 km# 按半径查询距离北京1000公里范围内的城市及距离
GEOSEARCH cities BYRADIUS 1000 km FROMMEMBER Beijing WITHDIST# 执行查询并将结果存储到另一个GeoSpatial结构中
GEOSEARCHSTORE result_cities BYRADIUS 1000 km FROMMEMBER Beijing WITHCOORD

这些命令扩展了Redis GeoSpatial在处理地理位置数据时的灵活性和功能性,适用于更复杂和精细化的地理空间数据分析和查询需求。

流(Stream)

Stream是一种高性能、持久化的数据结构,主要用于处理消息队列和日志系统,Stream通过简单而强大的命令集提供了高效的消息传输和处理方式,适用于实时数据处理、日志收集、消息队列等多种应用场景。使用Redis
Stream,可以轻松地实现消息的存储、传输和消费,并通过消费者组管理确保消息的有序处理和可靠传递

底层设计原理

1. 日志结构存储:

  • Stream基于日志(log)结构存储数据。每个Stream内部实际上是一个由多个条目(entry)组成的有序日志,每个条目都有唯一的ID,称为条目ID。

2. 条目ID生成:

  • 每个新添加到Stream的条目都会自动生成一个唯一的全局递增的ID。这个ID包含了一个64位的毫秒时间戳和一个序列号,确保了每个条目在Stream内的顺序和全局唯一性。

3. 内存结构与持久化:

  • Stream的条目可以部分保存在内存中,以保证高性能的写入和读取操作。Redis会根据配置的策略将部分或全部Stream数据持久化到磁盘上。

4. 消费者组:

  • Stream支持消费者组(consumer group),这是一种消费Stream消息的方式。每个消费者组可以有多个消费者,消费者可以独立或并行地处理消息,而无需担心重复消费或消息丢失。

5. 消费位置管理:

  • 每个消费者组中的消费者会记录自己消费的位置(offset),这个位置信息存储在Redis中。消费者组内的消费者可以通过ACK机制告知Redis已经处理完特定的消息,Redis根据ACK来更新消费位置,以确保消息不会被重复消费。

应用场景

1. 消息队列:

  • Stream可以作为高性能的消息队列使用,特别是在需要持久化、顺序保证和可靠传输的场景中,比如任务队列、实时通知等。

2. 日志系统:

  • 由于Stream内部是有序的日志结构,并且支持消费者组和持久化存储,因此非常适合作为日志收集和处理系统的基础。可以用于实时日志分析、事件溯源等场景。

3. 实时数据处理:

  • Stream的特性使其非常适合处理实时生成的数据流,比如实时监控、数据管道、实时分析等应用。

4. 消息发布订阅:

  • Stream可以替代传统的发布订阅(Pub/Sub)模式,提供更多的持久化和顺序保证。这对于需要持久订阅历史消息的应用非常有用。

5. 事件驱动架构:

  • 在微服务架构或事件驱动架构中,Stream可以作为事件消息的主要传输和存储方式,支持各种事件驱动的应用场景。

图例

// TODO

Stream使用方法

创建Stream

使用 XADD 命令向Stream中添加新条目:

  1. XADD mystream MAXLEN ~100 * field1 value1 field2 value2 …
  • mystream: Stream 的键名。
  • MAXLEN ~100: 可选参数,设置Stream的最大长度(条目数)。~ 表示不精确,即允许一定程度的超出。
  • *: 自动分配一个唯一的ID。
  • field1 value1 field2 value2 …: 条目的字段和值。
XADD mystream * sensor_id 1001 temperature 37.5 timestamp 1624142935.01234

读取Stream

使用 XREAD 命令从Stream中读取条目:
2. XREAD COUNT 10 STREAMS mystream 0

  • COUNT 10: 可选参数,指定读取的条目数。
  • STREAMS mystream 0: 0 表示从Stream中读取所有未读条目。
XREAD COUNT 5 STREAMS mystream 0

消费者组管理

创建消费者组:

XGROUP CREATE mystream mygroup $

读取和确认消息:

XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS mystream >
XACK mystream mygroup <message-id>

获取Stream信息

XINFO STREAM mystream

删除Stream中的条目

XDEL mystream <message-id>

使用示例

假设要创建一个名为 mystream 的Stream,并进行基本的操作:
1. 创建Stream并添加条目:

XADD mystream * sensor_id 1001 temperature 37.5 timestamp
1624142935.01234 XADD mystream * sensor_id 1002 temperature 36.8 timestamp 1624142945.01567

2. 读取Stream中的条目:

XREAD COUNT 2 STREAMS mystream 0

3. 创建消费者组并消费消息:
- 创建消费者组:

XGROUP CREATE mystream mygroup $

- 消费消息:

XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS mystream >
XACK mystream mygroup <message-id>

4. 获取Stream信息:

XINFO STREAM mystream

5. 删除条目:

XDEL mystream <message-id>

redis特性和优势

高性能:Redis 数据存储在内存中,操作非常快速。
持久化:支持多种持久化方式,可以将数据持久化到磁盘,保证数据安全。
复制和高可用:支持主从复制和 Sentinel 或 Cluster 方式的高可用解决方案。
事务:支持事务,可以批量执行一系列命令,保证原子性。
发布/订阅:支持发布与订阅模式,用于消息传递和通知。
丰富的功能扩展:通过 Lua 脚本和插件机制,可以扩展 Redis 的功能。

redis使用场景总结

缓存:作为高速缓存存储常用数据,加速访问速度。
会话存储:存储用户会话信息,实现无状态服务。
计数器:实现实时计数功能,如网站访问次数、商品销量等。
排行榜:通过有序集合存储用户积分和排名信息。
消息队列:利用列表和发布/订阅功能实现异步消息传递。

// TODO 未完待续

相关文章:

redis类型解析汇总

redis类型解析汇总 介绍数据类型简介主要数据类型&#xff1a;衍生类型&#xff1a; 字符串&#xff08;String&#xff09;底层设计原理图例设计优势字符串使用方法设置字符串值获取字符串值获取和设置部分字符串获取字符串长度追加字符串设置新值并返回旧值递增/递减同时设置…...

Unity3d自定义TCP消息替代UNet实现网络连接

以前使用UNet实现网络连接,Unity2018以后被弃用了。要将以前的老程序升到高版本,最开始打算使用Mirro,结果发现并不好用。那就只能自己写连接了。 1.TCP消息结构 (1). TCP消息是按流传输的,会发生粘包。那么在发射和接收消息时就需要对消息进行打包和解包。如果接收的消息…...

git fetch 和 git pull区别

git branch //查看本地所有分支 git branch -r //查看远程所有分支 git branch -a //查看本地和远程的所有分支 git branch <branchname> //新建分支 git branch -d <branchname> //删除本地分支 git branch -d -r <branchname> //删除远程分支&#x…...

冲击2024年CSDN博客之星TOP1:CSDN文章质量分查询在哪里?

文章目录 一&#xff0c;2023年博客之星规则1&#xff0c;不高的入围门槛2&#xff0c;[CSDN博文质量分测评地址](https://www.csdn.net/qc) 二&#xff0c;高分秘籍1&#xff0c;要有目录2&#xff0c;文章长度要足够&#xff0c;我的经验是汉字加代码至少1000字。3&#xff0…...

高性能并行计算华为云实验一:MPI矩阵运算

目录 一、实验目的 二、实验说明 三、实验过程 3.1 创建矩阵乘法源码 3.1.1 实验说明 3.1.2 实验步骤 3.2 创建卷积和池化操作源码 3.2.1 实验说明 3.2.2 实验步骤 3.3 创建Makefile文件并完成编译 3.4 建立主机配置文件与运行监测 四、实验结果与分析 4.1 矩阵乘法…...

库卡机器人减速机维修齿轮磨损故障

一、KUKA机器人减速器齿轮磨损故障的原因 1. 润滑不足&#xff1a;润滑油不足或质量不佳可能导致齿轮磨损。 2. 负载过重&#xff1a;超过库卡机械臂减速器额定负载可能导致齿轮磨损。 3. 操作不当&#xff1a;未按照说明书操作可能导致KUKA机器人减速器齿轮磨损。 4. 维护不足…...

【C/C++】我自己提出的数组探针的概念,快来围观吧

数组探针 在许多编程语言中如果涉及到数组那么就可以使用这个东西&#xff0c;便于遍历数组 中文名 数组探针 外文名 arrProbe 适用领域 大数据 所属学科 软件技术、编程 提出者 董翔 目录 1 概述2 工作原理3 应用场景 ▪ 数据处理和分析▪ 图像处理▪ 游戏开发▪…...

ArcGIS图斑分区(组)排序—从上到下从左到右

​​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 ArcGIS图斑分区&#xff08;组&#xff09;从上到下从左到右排序 是之前的内容的升级 GIS技巧100例——12ArcGIS图斑空间排序 关于今天的内容 我们在19年已经和大家分…...

React useRef 组件内及组件传参使用

保存变量&#xff0c; 改变不引起渲染 import { useRef} from react; const dataRef useRef(null) ... dataRef.current setTimeout(()>console.log(...),1000)绑定dom const inputRef useRef(null) <input ref {inputRef} />绑定dom列表 - ref 回调 const ite…...

Intelij IDEA中Mapper.xml无法构建到资源目录的问题

问题场景&#xff1a; 在尝试把原本在eclipse上的Java Web项目转移至Intelij idea上时&#xff0c;在配置文件均与eclipse一致的情况下出现了如下报错&#xff1a; org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): cn.umbrella.crm_core.…...

2024.6.23周报

目录 摘要 ABSTRACT 一、文献阅读 一、题目 二、摘要 三、网络架构 四、创新点 五、文章解读 1、Introduction 2、Method 3、实验 4、结论 二、代码实验 总结 摘要 本周阅读了一篇题目为NAS-PINN: NEURAL ARCHITECTURE SEARCH-GUIDED PHYSICS-INFORMED NEURAL N…...

鸿蒙实战开发:网络层的艺术——优雅封装与搭建指南(中)

前言 在鸿蒙开发的广袤天地中&#xff0c;网络层的搭建与封装无疑是构建高效、稳定应用的基石。继上篇的探索之后&#xff0c;本文将继续深入网络层的优化之旅&#xff0c;揭秘如何通过类型转换器、请求查询附加器以及丰富的常量参数&#xff0c;将网络层的构建艺术推向一个新…...

docker in docker 连私有仓库时报错 https

背景 jenkins 是使用 docker 方式部署的, 在 jenkins中又配置了 docker 的命令, 使用的宿主机的 docker 环境, 在jenkins 中执行 docker 相关命令的时候报错 jenkinse0e7b943b6e4:/$ docker login -u admin -p Harbor12345 172.16.100.15:80 WARNING! Using --password via t…...

mac怎么压缩pdf文件,苹果电脑怎么压缩pdf文件大小

在当今数字化时代&#xff0c;PDF文件已成为广泛使用的文档格式之一。然而&#xff0c;PDF 文件可能会因其包含的图像、图形和其他元素而导致文件较大&#xff0c;这可能会影响文件的传输、存储和共享。因此&#xff0c;对 PDF 文件进行压缩以减小其文件大小是很有必要的。今天…...

兴顺物流管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;驾驶员管理&#xff0c;物流资讯管理&#xff0c;车辆管理&#xff0c;基础数据管理 员工账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;物流资讯管理&…...

力扣(2024.06.21)

1. 54——螺旋矩阵 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 标签&#xff1a;数组&#xff0c;矩阵&#xff0c;模拟 代码&#xff1a; class Solution:def spiralOrder(self, matrix: List[List[int]]) -&…...

飞机大战java

"飞机大战"是一种经典的射击游戏&#xff0c;通常在各种平台上都有实现&#xff0c;包括Java。如果你想要开发一个Java版本的飞机大战游戏&#xff0c;你可能需要考虑以下几个方面&#xff1a; 游戏设计&#xff1a;确定游戏的基本规则&#xff0c;比如玩家控制的飞机…...

Springboot的自动配置原理

文章目录 Springboot的自动配置原理?1. Spring Boot Starter 依赖2.SpringBootApplication注解3.自动触发配置4.Auto-configuration Classes5.条件注解6. 外部配置文件7. 优先级和排除总结 Springboot的自动配置原理? 1. Spring Boot Starter 依赖 Spring Boot 提供了各种 …...

Interview preparation--elascitSearch深分页问题

深度分页出现原因 当我们需要查询的数据页数特别大的时候&#xff0c;比如from size 大于10000 的时候&#xff0c;可能出现“window is too large” 异常&#xff0c;如下网图&#xff1a; 查询语句如下 { "query": { "bool": { "must": [ {…...

C语言笔试题:实现把一个无符号整型数字的二进制序列反序后输出

目录 题目 实例 方法一&#xff1a;直接交换 方法二&#xff1a;间接交换 拓展 题目 编写一个函数&#xff0c;将一个无符号整数的所有位逆序&#xff08;在32位机器下&#xff09; 实例 例如有一个无符号整数 unsigned int num 32; unsigned int 在32位系统中占4个字…...

elementplus如何实现dialog遮罩层外的元素可以被操作点击

elementplus如何实现dialog遮罩层外的元素可以被操作点击 element plus 组件库中的 dialog 组件可以说是使用频率最高的组件之一&#xff0c;它的效果是弹出一个对话框&#xff0c;外面默认会有一个蒙层。 现在我碰到的需求是&#xff0c;弹窗要正常显示&#xff0c;但是蒙层下…...

Springboot整合Kafka消息队列服务实例

一、Kafka相关概念 1、关于Kafka的描述 Kafka是由Apache开源&#xff0c;具有分布式、分区的、多副本的、多订阅者&#xff0c;基于Zookeeper协调的分布式处理平台&#xff0c;由Scala和Java语言编写。通常用来搜集用户在应用服务中产生的动作日志数据&#xff0c;并高速的处…...

kotlin——MVVM框架下的大型项目优化

目录 概要 优化思路 一、重构过长的Activity 二、优化臃肿的ViewModel 示例代码&#xff1a; 概要 在大型项目中&#xff0c;随着项目越做越大&#xff0c;activity和viewmodel的代码会越来越多&#xff0c;尽量保持Activity和ViewModel的代码精简和易于维护是非常重要的。个人…...

echarts实现折线图点击添加标记

文章目录 背景一、代码示例 背景 业务场景体现在功能层面主要两点&#xff0c; 折线图表设置点击事件点击事件与图标渲染标记绑定 对于节点没有被添加标记的可以&#xff0c;弹框提示添加标记&#xff0c;并提供标记内容输入框&#xff0c;已经添加过标记的点&#xff0c;点…...

循环赛日程表

描述 n 2 ^ k个选手 每个选手必须与其他n-1个选手各赛一次每个选手一天赛一次比赛打n-1天 思路 k 3时的解 我们先进行假设&#xff1a;每个选手第一天和自己比&#xff0c;然后分解成4个子问题&#xff1a; (1)14号的第14天&#xff0c;对手1~4号; (2)14号的第58天&a…...

计算机网络:运输层 - 概述

计算机网络&#xff1a;运输层 - 概述 运输层的任务端口号复用与分用UDP协议首部格式 TCP协议面向字节流 运输层的任务 物理层、数据链路层以及网络层&#xff0c;他们共同解决了将主机通过网络互联起来所面临的问题&#xff0c;实现了主机到主机的通信。 网络层的作用范围是…...

使用阿里开源的Spring Cloud Alibaba AI开发第一个大模型应用

背景 前段时间看到Spring推出了SpringAI&#xff0c;可以方便快速的接入ChatGPT等国外的大模型&#xff0c;现在阿里巴巴也紧追脚步推出了Spring Cloud Alibaba AI&#xff0c;Spring Cloud Alibaba AI 目前基于 Spring AI 0.8.1 版本 API 完成通义系列大模型的接入。通义接入…...

`THREE.PointsMaterial` 是 Three.js 中用于创建粒子系统材质的类。它允许你设置粒子系统的外观属性,比如颜色、大小和透明度。

demo案例 THREE.PointsMaterial 是 Three.js 中用于创建粒子系统材质的类。它允许你设置粒子系统的外观属性&#xff0c;比如颜色、大小和透明度。下面是对其构造函数的参数、属性和方法的详细讲解。 构造函数 const material new THREE.PointsMaterial(parameters);参数&am…...

Android-Android Studio-FAQ

1 需求 2 接口 3 Android Studio xml布局代码补全功能失效问题 最终解决方案就是尝试修改compileSdk 为不同SDK版本来解决问题&#xff0c;将原本34修改为32测试会发现xml代码补全功能有效了&#xff01; 参考资料 Android Studio xml布局代码补全功能失效问题_android studi…...

架构师指南:现代 Datalake 参考架构

这篇文章的缩写版本于 2024 年 3 月 26 日出现在 The New Stack 上。 旨在最大化其数据资产的企业正在采用可扩展、灵活和统一的数据存储和分析方法。这一趋势是由企业架构师推动的&#xff0c;他们的任务是制定符合不断变化的业务需求的基础设施。现代数据湖体系结构通过将数…...

通讯协议大全(UART,RS485,SPI,IIC)

参考自&#xff1a; 常见的通讯协议总结&#xff08;USART、IIC、SPI、485、CAN&#xff09;-CSDN博客 UART那么好用&#xff0c;为什么单片机还需要I2C和SPI&#xff1f;_哔哩哔哩_bilibili 5分钟看懂!串口RS232 RS485最本质的区别&#xff01;_哔哩哔哩_bilibili 喜欢几位…...

基于EXCEL数据表格创建省份专题地图

1 数据源 随着西藏于5月1日发布2022年一季度经济运行情况&#xff0c;31省份一季度GDP数据已全部出炉。 总量方面&#xff0c;粤苏鲁稳居前三&#xff1b;增速方面&#xff0c;23省份高于“全国线”&#xff0c;新疆表现最佳&#xff0c;增速达到7.0%。 表格表现数据不够直观…...

基于java+springboot+vue实现的电商应用系统(文末源码+Lw)241

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本电商应用系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&a…...

好文!12个策略解决 Kafka 数据丢失问题

哥们儿&#xff01;有遇到Kafka数据丢失问题的问题吗&#xff0c;你是如何解决的&#xff1f;今天的文章&#xff0c;V哥来详细解释一下&#xff0c;整理了12种解决策略&#xff0c;希望可以帮助你解决项目中的问题&#xff1a;以下是一些常见的解决方案和最佳实践。 生产者确认…...

Android 第三方框架:网络:OkHttp:源码分析:拦截器

文章目录 涉及到的设计模式 责任链模式:ArrayList策略模式:Interceptor和XXXInterceptor源码分析API总结涉及到的设计模式 责任链模式:ArrayList ArrayList 用ArrayList作为保存顺序的数据结构 把系统提供的各种Interceptor和自定义的Interceptor放入ArrayList中 RealI…...

FlowUs AI的使用教程和使用体验

FlowUs AI 使用教程 FlowUs AI特点使其成为提升个人和团队生产力的有力工具&#xff0c;无论是在学术研究、内容创作、技术开发还是日常办公中都能发挥重要作用。现在来看看如何使用FlowUs AI吧&#xff01; 注册与登录&#xff1a;首先&#xff0c;确保您已经注册并登录FlowU…...

SwiftUI 6.0(iOS 18)ScrollView 全新的滚动位置(ScrollPosition)揭秘

概览 在只有方寸之间大小的手持设备上要想体面的向用户展示海量信息&#xff0c;滚动视图&#xff08;ScrollView&#xff09;无疑是绝佳的“东牀之选”。 在 SwiftUI 历史的长河中&#xff0c;总觉得苹果对于 ScrollView 视图功能的升级是在“挤牙膏”。这不&#xff0c;在本…...

阿贝云免费虚拟主机和免费云服务器评测

阿贝云是一家提供免费虚拟主机和免费云服务器的服务商&#xff0c;为用户提供了一个便捷的搭建网站和应用的平台。他们的服务受到了很多用户的好评。用户可以轻松地在阿贝云上创建自己的网站&#xff0c;并享受免费的虚拟主机和云服务器。通过阿贝云的服务&#xff0c;用户可以…...

不懂就问,开通小程序地理位置接口有那么难吗?

小程序地理位置接口有什么功能&#xff1f; 若提审后被驳回&#xff0c;理由是“当前提审小程序代码包中地理位置相关接口( chooseAddress、getLocation )暂未开通&#xff0c;建议完成接口开通后或移除接口相关内容后再进行后续版本提审”&#xff0c;那么遇到这种情况&#x…...

Python 全栈系列256 异步任务与队列消息控制(填坑)

说明 每个创新都会伴随着一系列的改变。 在使用celery进行异步任务后&#xff0c;产生的一个问题恰好也是因为异步产生的。 内容 1 问题描述 我有一个队列 stream1, 对应的worker1需要周期性的获取数据&#xff0c;对输入的数据进行模式识别后分流。worker1我设施为10秒运行…...

从零开始的Ollama指南:部署私域大模型

大模型相关目录 大模型&#xff0c;包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步&#xff0c;扬帆起航。 大模型应用向开发路径&#xff1a;AI代理工作流大模型应用开发实用开源项目汇总大模…...

C++类和对象总结

目录 总结 一、引言 二、类的定义 三、对象的创建与初始化 四、访问控制 五、封装 六、继承 七、多态 八、其他特性 九、总结 C类的定义 C对象的创建和初始化 C类的访问控制 总结 一、引言 C是一种面向对象的编程语言&#xff0c;其核心概念是类和对象。类是对现…...

基于PHP的民宿管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的民宿管理系统 一 介绍 此民宿管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端jquery.js和echarts.js。系统角色分为用户和管理员。用户可以在线浏览和预订民宿&#xff0c;管理员登录后台进行相关管理等。(在系统…...

ROS中C++、Python完整的目录结构

文章目录 在ROS中&#xff0c;一个典型的C软件包目录结构通常包括以下几个主要目录&#xff1a; include&#xff1a;该目录包含C头文件&#xff08;.hpp或者.h文件&#xff09;&#xff0c;用于声明类、函数、变量等。通常&#xff0c;这些头文件定义了ROS节点、消息类型、服务…...

Boosting原理代码实现

1&#xff0e;提升方法是将弱学习算法提升为强学习算法的统计学习方法。在分类学习中&#xff0c;提升方法通过反复修改训练数据的权值分布&#xff0c;构建一系列基本分类器&#xff08;弱分类器&#xff09;&#xff0c;并将这些基本分类器线性组合&#xff0c;构成一个强分类…...

【Qt基础教程】事件

文章目录 前言事件简介事件示例总结 前言 在开发复杂的图形用户界面(GUI)应用程序时&#xff0c;理解和掌握事件处理是至关重要的。Qt&#xff0c;作为一个强大的跨平台应用程序开发框架&#xff0c;提供了一套完整的事件处理系统。本教程旨在介绍Qt事件处理的基础知识&#x…...

外星人Alienware m15R7 原厂Windows11系统

装后恢复到您开箱的体验界面&#xff0c;包括所有原机所有驱动AWCC、Mydell、office、mcafee等所有预装软件。 最适合您电脑的系统&#xff0c;经厂家手调试最佳状态&#xff0c;性能与功耗直接拉满&#xff0c;体验最原汁原味的系统。 原厂系统下载网址&#xff1a;http://w…...

stata17中java installation not found或java not recognozed的问题

此问题在于stata不知道去哪里找java,因此需要手动的告诉他 方法1&#xff1a; 1.你得保证已经安装并配置好java环境 2.在stata中输入以下内容并重启stata即可 set java_home "D:\Develope\JDk17" 其中java_home后面的""里面的内容是你的jdk安装路径 我的…...

Harbor本地仓库搭建003_Harbor常见错误解决_以及各功能使用介绍_镜像推送和拉取---分布式云原生部署架构搭建003

首先我们去登录一下harbor,但是可以看到,用户名密码没有错,但是登录不上去 是因为,我们用了负债均衡,nginx会把,负载均衡进行,随机分配,访问的 是harbora,还是harborb机器. loadbalancer中 解决方案,去loadbalance那个机器中,然后 这里就是25机器,我们登录25机器 然后去配置…...

怎样搭建serveru ftp个人服务器

首先说说什么是ftp&#xff1f; FTP协议是专门针对在两个系统之间传输大的文件这种应用开发出来的&#xff0c;它是TCP/IP协议的一部分。FTP的意思就是文件传输协议&#xff0c;用来管理TCP/IP网络上大型文件的快速传输。FTP早也是在Unix上开发出来的&#xff0c;并且很长一段…...