分布式文件存储与数据缓存 Redis高可用分布式实践(上)(三)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 分布式文件存储与数据缓存 Redis高可用分布式实践(上)(三)

3.4 Set类型

简介

与List类似是一个列表功能,但Set是自动排重的,当需要存储一个列表数据,又不希望出现重复数据时,Set是一个很好的选择。

Set是String类型的无序集合,它底层其实是一个value为null的hash表,所以添加、删除、查找的时间复杂度都是O(1)。

sadd

将一个或多个元素添加到集合key中,已经存在的元素将被忽略。

sadd key value1 value2……

示例:

#向集合中添加值,最终只有v1 v2 v3 v4 v5 v6
127.0.0.1:6379> sadd k1 v1 v2 v2 v3 v4 v5 v6

smembers

取出该集合的所有元素。

smembers key

示例:

127.0.0.1:6379> smembers k1
1) "v2"
2) "v1"
3) "v3"

sismember

判断集合key中是否含有value元素,如有返回1,否则返回0。

sismember key value

示例:

127.0.0.1:6379> sismember k1 v1
(integer) 1
127.0.0.1:6379>

scard

返回该集合的元素个数。

scard key

示例:

127.0.0.1:6379> scard k1
(integer) 3
127.0.0.1:6379>

srem

删除集合中的一个或多个成员元素,不存在的成员元素会被忽略。

srem key value1 value2……

示例:

# 删除v1 v2
srem k1 v1 v2

spop

随机删除集合中一个元素并返回该元素。

spop key

示例:

spop k1 随机删除一个元素,并返回

srandmember

随机取出集合中count个元素,但不会删除。

srandmember key count

示例:

#随机取出集合中的2个元素
srandmember k1 2

smove

将value元素从sourcekey集合移动到destinationkey集合中。

smove sourcekey destinationkey value

示例:

smove k1 k2 v5 将元素v5从集合k1中移动到集合k2

注意:

如果 sourcekey集合不存在或不包含指定的 value元素,则 smove 命令不执行任何操作,仅返回 0 。

sinter

返回两个集合的交集元素。

sinter key1 key2

sunion

返回两个集合的并集元素。

sunion key1 key2

sdiff

返回两个集合的差集元素(key1中的,不包含key2)

sdiff key1 key2

使用场景

  • 黑白名单
  • 随机展示
  • 好友
  • 关注人
  • 粉丝
  • 感兴趣的人集合

3.4 Hash类型

简介

Hash是一个键值对的集合。Hash 是一个 String 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。

  • Hash存储结构优化
  • 如果field数量较少,存储结构优化为类数组结构
  • 如果field数量较多,存储结构使用HashMap结构

hset

给key集合中的field赋值value。相当于是为实体类的属性赋值,此时的属性就相当于是key,属性的值相当于是value。

hset key field value

示例:

#为实体类user的属性name赋值为zhangsan
127.0.0.1:6379> hset user name zhangsan

注意:

  • 如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。
  • 如果字段已经存在于哈希表中,旧值将被重写。

hget

从key哈希中,取出field字段的值。相当于是获取实体类哪个属性的值。

hget key field

示例:

#获取实体类user的name属性
127.0.0.1:6379> hget user name
"zhangsan"

hmset

批量设置哈希的字段及值。

hmset key field1 value1 field2 value2……

示例:

#为user实体类设置name、age、addres属性并赋值
127.0.0.1:6379> hmset user name zhangsan age 19 address shandong
OK

hexists

判断指定key中是否存在某个属性。

hexists key field

示例:

#判断user实体类中是否存在name属性
127.0.0.1:6379> hexists user name
(integer) 1

注意:

如果哈希表含有给定字段,返回 1 。 如果哈希表不含有给定字段,或 key 不存在,返回 0 。

hkeys

获取该哈希中所有的field。获取该实体类的属性。

#获取user实体类的全部属性
127.0.0.1:6379> hkeys user
1) "name"
2) "age"
3) "address"

hvals key

获取该哈希中所有的value。获取该实体类的属性值。

hvals key

示例:

127.0.0.1:6379> hvals user
1) "zhangsan"
2) "19"
3) "shandong"

hincrby

为哈希表key中的field字段的值加上增量increment。

hincrby key field increment

示例:

#为实体类user的属性age增1
127.0.0.1:6379> hincrby user age 1
(integer) 20

hdel

删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略。

hdel key field1 field2……

示例:

#删除user实体类的age和address属性
127.0.0.1:6379> hdel user age address
(integer) 2

hsetnx

给key哈希表中不存在的的字段赋值 。

hsetnx key field value

示例:

#为user中不存在的属性age赋值,因为age属性不存在所以可以赋值。
127.0.0.1:6379> hset user age 10
(integer) 1
#因为name属性不存在所以无法为该属性赋值
127.0.0.1:6379> hset user name zhangsan
(integer) 0

注意:

  • 如果哈希表不存在,一个新的哈希表被创建并进行 hsetnx 操作。
  • 如果字段已经存在于哈希表中,操作无效。
  • 如果 key 不存在,一个新哈希表被创建并执行 hsetnx 命令。

使用场景

  • 购物车
  • 存储对象

3.5 Zset

简介

Zset与Set非常相似,是一个没有重复元素的String集合。不同之处是Zset的每个元素都关联了一个分数(score),这个分数被用来按照从低分到高分的方式排序集合中的元素。集合的元素是唯一的,但分数可以重复。-

注意:

因为元素是有序的,所以可以根据分数(score)或者次序(position)来获取一个范围内的元素。

zadd

将一个或多个元素(value)及分数(score)加入到有序集key中。

zadd key score1 value1 score2 value2……

示例:

#java分数是100,c++分数200,c分数300
127.0.0.1:6379> zadd k1 100 java 200 c++ 300 C
(integer) 3

注意:

  • 如果某个元素已经是有序集的元素,那么更新这个元素的分数值,并通过重新插入这个元素,来保证该元素在正确的位置上。
  • 分数值可以是整数值或双精度浮点数。
  • 如果有序集合 key 不存在,则创建一个空的有序集并执行 zadd 操作。

zrange

返回key集合中的索引start和索引end之间的元素(包含start和end)。

zrange key start end [withscores]

示例:

#返回集合中全部的元素
127.0.0.1:6379> zrange k1 0 -1
1) "java"
2) "c++"
3) "C"
#返回集合中的元素和分数
127.0.0.1:6379> zrange k1 0 -1 withscores
1) "java"
2) "100"
3) "c++"
4) "200"
5) "C"
6) "300"

注意:

  • 其中元素的位置按分数值递增(从小到大)来排序。 其中 0 表示列表的第一个元素,-1表示最后一个元素。
  • withscores是可选参数,是否返回分数。

zrangebyscore

返回key集合中的分数minscore 和分数maxscore 之间的元素(包含minscore 和maxscore )。其中元素的位置按分数值递增(从小到大)来排序。

zrangebyscore key  minscore maxscore [withscores]

示例:

127.0.0.1:6379> zrangebyscore k1 100  300 [withscores]
1) "java"
2) "c++"
3) "C"

zincrby

为元素value的score加上increment的值。

zincrby key increment value

示例:

#给Java加50
127.0.0.1:6379> zincrby k1 50 java 
"150"

zrem

删除该集合下value的元素。

zrem k1 php 删除php

zcount

统计该集合在minscore 到maxscore分数区间中元素的个数。

zcount key minscore maxscore

示例:

zcount k1 100 300 统计100分到300分中间元素的个数

zrank

返回value在集合中的排名,从0开始。

zrank key value

示例:

zrank k1 c++ 返回c++排名

使用场景

  • 延时队列
  • 排行榜
  • 限流

3.6 itmaps类型(较难理解)

简介

在计算机中,用二进制(位)作为存储信息的基本单位,1个字节等于8位。

例如 "abc" 字符串是由 3 个字节组成,计算机存储时使用其二进制表示,"abc"分别对应的ASCII码是97、98、99,对应的二进制是01100001、01100010、01100011,在内存中表示如下:

合理地使用位能够有效地提高内存使用率和开发效率。

Redis提供了Bitmaps这个 “数据结构” 可以实现对位的操作:

setbit

设置Bitmaps中某个偏移量的值。

setbit key offset value

示例:

redis中bitmaps可以用来统计用户信息,eg:活跃天数、打卡天数、登录天数

bitmaps位图,都是操作二进制来进行记录,就只有0和1两个状态

统计zhangsan4月份考勤情况,第二个数字代表的是天,第三个数字代表是否迟到:1未迟到0迟到
127.0.0.1:6379> bitcount zhangsan
(integer) 0
127.0.0.1:6379> setbit zhangsan:4 1 1
(integer) 1
127.0.0.1:6379> setbit zhangsan:4 2 1
(integer) 1
127.0.0.1:6379> setbit zhangsan:4 3 0
(integer) 0
127.0.0.1:6379> setbit zhangsan:4 4 1
(integer) 1

注意 最后一个数字是偏移量的值,倒数第二个叫偏移量。

getbit

获取Bitmaps中某个偏移量的值。

getbit key offset

示例:

获取key的offset 的值。

127.0.0.1:6379> getbit zhangsan 3
(integer) 0

bitcount

统计字符串被设置为1的bit数量。一般情况下,给定的整个字符串都会被进行统计,可以选择通过额外的start和end参数,指定字节组范围内进行统计(包括start和end),0表示第一个元素,-1表示最后一个元素。

bitcount key [start end]

示例:

bitcount sign 获取整个字符串被设置为1的bit数量,结果为3

如:当前存在一个key为k1的bitmaps存储着[00000001,00000001,00000010,00000011],分别对应[1,1,2,3]。

setbit num 7 1  
setbit num 15 1
setbit num 22 1
setbit num 30 1
setbit num 31 1
bitcount num 1 2 统计索引1、2两个字节组中bit=1的数量,即统计00000001,00000010中bit=1的数量,结果为2
bitcount num 1 3 统计索引1、2、3三个字节组中bit=1的数量,即统计00000001,00000010,00000011中bit=1的数量,结果为4
bitcount num 0 -1 统计所有的字节组中bit=1的数量,结果为5

setbit设置或获取的是bit(位)的位置,bitcount计算的是byte(字节)位置。

bitop

将多个bitmaps通过求交集/并集方式合并成一个新的bitmaps。

bitop and/or destkey sourcekey1 sourcekey2……

示例:

bitop and k3 k1 k2 通过求交集将k1 k2合并成k3
bitop or k3 k1 k2  通过求并集将k1 k2合并成k3

使用场景

  • 活跃天数
  • 打卡天数
  • 登录天数
  • 用户签到
  • 统计活跃用户
  • 统计用户是否在线
  • 实现布隆过滤器

3.7 Geospatia

简介

GEO,Geographic,地理信息的缩写。该类型就是元素的二维坐标,在地图上就是经纬度。Redis基于该类型,提供了经纬度设置、查询、范围查询、距离查询、经纬度Hash等常见操作。

geoadd

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

geoadd key longitude latitude member

示例:

# 将北京的经纬度和名称添加到china
geoadd china 116.405285 39.904989 beijing 
# 将成都和上海的经纬度、名称添加到china
geoadd china 104.065735 30.659462 chengdu 121.472644 31.231706 shanghai

geopos

从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil。

geopos key member [member ……]

示例:

#返回china中名称为shanghai和beijing的经纬度
geopos china shanghai beijing

geodist

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

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

参数说明:

  • m :米,默认单位。
  • km :千米。
  • mi :英里。
  • ft :英尺。
# 返回shanghai和beijing之间的距离,结果1067597.9668,单位米
geodist chinacity shanghai beijing 
# 返回shanghai和chengdu之间的距离,结果1660.0198,单位是千米
geodist chinacity shanghai chengdu km

georadius

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

georadius key longitude latitude radius m|km|ft|mi

示例:

#获取经纬度110 30为中心,在china内1200公里范围内的所有元素。
georadius china 110 30 1200 km

使用场景

  • 附近的电影院
  • 附近的好友
  • 离最近的火锅店

前提是将这些商铺的坐标放到redis

3.8 HyperLogLog

简介

在我们做站点流量统计的时候一般会统计页面UV(独立访客:unique visitor)和PV(即页面浏览量:page view)。redis HyperLogLog是用来做基数统计的算法,HyperLogLog的优点是:在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且使很小的。

什么是基数

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

pfadd

将所有元素参数添加到 Hyperloglog 数据结构中。

pfadd key element1 element2……

示例:

如果至少有个元素被添加返回 1, 否则返回 0。

pfadd book1 uid1 uid2 uid3

注意:

添加元素到HyperLogLog中,如果内部有变动返回1,没有返回0。

pfcount

计算Hyperloglog 近似基数,可以计算多个Hyperloglog ,统计基数总数。

pfcount key1 key2……

示例:

pfcount book1       #计算book1的基数,结果为3
pfadd book2 uid3 uid4   #添加两个元素到book2中
pfcount book1 book2    #统计两个key的基数总数,结果为5

pfmerge

将一个或多个Hyperloglog(sourcekey1) 合并成一个Hyperloglog (destkey )。

pfmerge destkey sourcekey1 sourcekey2……

示例:

比如每月活跃用户可用每天活跃用户合并后计算。

#将book1和book2合并成book,结果为5
pfmerge book book1 book2

使用场景

基数不大,数据量不大就用不上,会有点大材小用浪费空间,有局限性,就是只能统计基数数量,而没办法去知道具体的内容是什么,和bitmap相比,属于两种特定统计情况,简单来说,HyperLogLog 去重比 bitmaps 方便很多,一般可以bitmap和hyperloglog配合使用,bitmap标识哪些用户活跃。

  • 网站PV统计
  • 网站UV统计
  • 统计访问量(IP数)
  • 统计在线用户数
  • 统计每天搜索不同词条的个数
  • 统计文章真实阅读数


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
6天前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
7天前
|
存储 缓存 NoSQL
【赵渝强老师】基于Redis的旁路缓存架构
本文介绍了引入缓存后的系统架构,通过缓存可以提升访问性能、降低网络拥堵、减轻服务负载和增强可扩展性。文中提供了相关图片和视频讲解,并讨论了数据库读写分离、分库分表等方法来减轻数据库压力。同时,文章也指出了缓存可能带来的复杂度增加、成本提高和数据一致性问题。
【赵渝强老师】基于Redis的旁路缓存架构
|
7天前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
40 16
|
15天前
|
缓存 NoSQL Redis
Redis 缓存使用的实践
《Redis缓存最佳实践指南》涵盖缓存更新策略、缓存击穿防护、大key处理和性能优化。包括Cache Aside Pattern、Write Through、分布式锁、大key拆分和批量操作等技术,帮助你在项目中高效使用Redis缓存。
90 22
|
14天前
|
缓存 NoSQL 中间件
redis高并发缓存中间件总结!
本文档详细介绍了高并发缓存中间件Redis的原理、高级操作及其在电商架构中的应用。通过阿里云的角度,分析了Redis与架构的关系,并展示了无Redis和使用Redis缓存的架构图。文档还涵盖了Redis的基本特性、应用场景、安装部署步骤、配置文件详解、启动和关闭方法、systemctl管理脚本的生成以及日志警告处理等内容。适合初学者和有一定经验的技术人员参考学习。
103 7
|
19天前
|
存储 缓存 监控
利用 Redis 缓存特性避免缓存穿透的策略与方法
【10月更文挑战第23天】通过以上对利用 Redis 缓存特性避免缓存穿透的详细阐述,我们对这一策略有了更深入的理解。在实际应用中,我们需要根据具体情况灵活运用这些方法,并结合其他技术手段,共同保障系统的稳定和高效运行。同时,要不断关注 Redis 缓存特性的发展和变化,及时调整策略,以应对不断出现的新挑战。
52 10
|
21天前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:百万级数据统计优化实践
【10月更文挑战第21天】 在处理大规模数据集时,传统的单体数据库解决方案往往力不从心。MySQL和Redis的组合提供了一种高效的解决方案,通过将数据库操作与高速缓存相结合,可以显著提升数据处理的性能。本文将分享一次实际的优化案例,探讨如何利用MySQL和Redis共同实现百万级数据统计的优化。
54 9
|
19天前
|
缓存 监控 NoSQL
Redis 缓存穿透的检测方法与分析
【10月更文挑战第23天】通过以上对 Redis 缓存穿透检测方法的深入探讨,我们对如何及时发现和处理这一问题有了更全面的认识。在实际应用中,我们需要综合运用多种检测手段,并结合业务场景和实际情况进行分析,以确保能够准确、及时地检测到缓存穿透现象,并采取有效的措施加以解决。同时,要不断优化和改进检测方法,提高检测的准确性和效率,为系统的稳定运行提供有力保障。
47 5
|
16天前
|
存储 缓存 算法
分布式缓存有哪些常用的数据分片算法?
【10月更文挑战第25天】在实际应用中,需要根据具体的业务需求、数据特征以及系统的可扩展性要求等因素综合考虑,选择合适的数据分片算法,以实现分布式缓存的高效运行和数据的合理分布。