Go新项目-调研关于go项目中redis的使用场景,lua实战(7)

这篇具有很好参考价值的文章主要介绍了Go新项目-调研关于go项目中redis的使用场景,lua实战(7)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Go新项目-调研关于go项目中redis的使用场景,lua实战(7),Go,golang,redis,lua

参考地址

  • https://juejin.cn/post/7079756129433370638
  • https://blog.csdn.net/gaogaoshan/article/details/41039581
  • https://redis.io/docs/clients/go/

redis的使用场景的解释

下面一一来分析下Redis的应用场景都有哪些。

1、缓存

缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力。Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓存的场合非常多。

2、排行榜

很多网站都有排行榜应用的,如京东的月度销量榜单、商品按时间的上新排行榜等。Redis提供的有序集合数据类构能实现各种复杂的排行榜应用。

3、计数器

什么是计数器,如电商网站商品的浏览量、视频网站视频的播放数等。为了保证数据实时效,每次浏览都得给+1,
并发量高时如果每次都请求数据库操作无疑是种挑战和压力。Redis提供的incr命令来实现计数器功能,内存操作,性能非常好,非常适用于这些计数场景。

4、分布式会话

集群模式下,在应用不多的情况下一般使用容器自带的session复制功能就能满足,当应用增多相对复杂的系统中,一般都会搭建以Redis等内存数据库为中心
的session服务,session不再由容器管理,而是由session服务及内存数据库管理。

5、分布式锁

在很多互联网公司中都使用了分布式技术,分布式技术带来的技术挑战是对同一个资源的并发访问,如全局ID、减库存、秒杀等场景,
并发量不大的场景可以使用数据库的悲观锁、乐观锁来实现,但在并发量高的场合中,利用数据库锁来控制资源的并发访问是不太理想的,
大大影响了数据库的性能。可以利用Redis的setnx功能来编写分布式的锁,如果设置返回1说明获取锁成功,否则获取锁失败,实际应用中要考虑的细节要更多。

6、社交网络

点赞、踩、关注/被关注、共同好友等是社交网站的基本功能,社交网站的访问量通常来说比较大,而且传统的关系数据库类型不适合存储这种类型的数据,
Redis提供的哈希、集合等数据结构能很方便的的实现这些功能。

7、最新列表

Redis列表结构,LPUSH可以在列表头部插入一个内容ID作为关键字,LTRIM可用来限制列表的数量,这样列表永远为N个ID,无需查询最新的列表,
直接根据ID去到对应的内容页即可。

8、消息系统

消息队列是大型网站必用中间件,如ActiveMQ、RabbitMQ、Kafka等流行的消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低的业务。
Redis提供了发布/订阅及阻塞队列功能,能实现一个简单的消息队列系统。另外,这个不能和专业的消息中间件相比。

9、地理位置

使用Redis的Geo数据类型可以存储地理位置信息,实现地理位置相关的查询和分析。

10、搜索引擎

Redis的Sorted Set可以用来存储有序数据,例如排行榜、搜索结果等。
在Go语言中,可以使用ZADD、ZRANGE等命令来实现对Sorted Set的操作,实现搜索引擎的功能。

常用命令

  • SET 和 GET:用于设置和获取字符串类型的值;
  • HSET、HGET、HMSET、HMGET:用于设置和获取哈希类型的值;
  • LPUSH、RPUSH、LPOP、RPOP:用于操作列表类型的值;
  • SADD、SREM、SMEMBERS:用于操作集合类型的值;
  • ZADD、ZREM、ZRANGE:用于操作有序集合类型的值;
  • INCR、INCRBY、DECR、DECRBY:用于对整数类型的值进行原子性的加减操作;
  • EXPIRE、TTL:用于设置和查询键的过期时间;
  • PUBLISH、SUBSCRIBE:用于实现 Redis 的发布订阅功能;
  • MULTI、EXEC、WATCH、UNWATCH:用于实现 Redis 的事务功能;
  • SCAN:用于迭代大量的键,避免阻塞 Redis 服务器。

实际场景

  • 缓存
  • 数据共享分布式
  • 分布式锁
  • 全局ID
  • 计数器
  • 限流
  • 位统计
  • 购物车
  • 用户消息时间线timeline
  • 消息队列
  • 抽奖
  • 点赞、签到、打卡
  • 商品标签
  • 商品筛选
  • 用户关注、推荐模型
  • 排行榜
1、缓存

String类型

例如:热点数据缓存(例如报表、明星出轨),对象缓存、全页缓存、可以提升热点数据的访问数据。

2、数据共享分布式

String 类型,因为 Redis 是分布式的独立服务,可以在多个应用之间共享

例如:分布式Session

<dependency> 
 <groupId>org.springframework.session</groupId> 
 <artifactId>spring-session-data-redis</artifactId> 
</dependency>
3、分布式锁

String 类型setnx方法,只有不存在时才能添加成功,返回true

public static boolean getLock(String key) {
Long flag = jedis.setnx(key, "1");
if (flag == 1) {
jedis.expire(key, 10);
}
return flag == 1;
}

public static void releaseLock(String key) {
jedis.del(key);
}
4、全局ID

int类型,incrby,利用原子性

incrby userid 1000

分库分表的场景,一次性拿一段

5、计数器
int类型,incr方法

例如:文章的阅读量、微博点赞数、允许一定的延迟,先写入Redis再定时同步到数据库

6、限流

int类型,incr方法

以访问者的ip和其他信息作为key,访问一次增加一次计数,超过次数则返回false

7、位统计

String类型的bitcount(1.6.6的bitmap数据结构介绍)

字符是以8位二进制存储的

set k1 a
setbit k1 6 1
setbit k1 7 0
get k1
/* 6 7 代表的a的二进制位的修改
a 对应的ASCII码是97,转换为二进制数据是01100001
b 对应的ASCII码是98,转换为二进制数据是01100010

因为bit非常节省空间(1 MB=8388608 bit),可以用来做大数据量的统计。
*/

例如:在线用户统计,留存用户统计

setbit onlineusers 01
setbit onlineusers 11
setbit onlineusers 20

支持按位与、按位或等等操作

BITOPANDdestkeykey[key...] ,对一个或多个 key 求逻辑并,并将结果保存到 destkey 。       
BITOPORdestkeykey[key...] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey 。
BITOPXORdestkeykey[key...] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey 。
BITOPNOTdestkeykey ,对给定 key 求逻辑非,并将结果保存到 destkey 。

计算出7天都在线的用户

BITOP "AND" "7_days_both_online_users" "day_1_online_users" "day_2_online_users" ...  "day_7_online_users"
8、购物车

String 或hash。所有String可以做的hash都可以做

key:用户id;field:商品id;value:商品数量。
+1:hincr。-1:hdecr。删除:hdel。全选:hgetall。商品数:hlen。
9、用户消息时间线timeline

list,双向链表,直接作为timeline就好了。插入有序

10、消息队列

List提供了两个阻塞的弹出操作:blpop/brpop,可以设置超时时间

blpop:blpop key1 timeout 移除并获取列表的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
brpop:brpop key1 timeout 移除并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
上面的操作。其实就是java的阻塞队列。学习的东西越多。学习成本越低
  • 队列:先进先除:rpush blpop,左头右尾,右边进入队列,左边出队列
  • 栈:先进后出:rpush brpop
11、抽奖

自带一个随机获得值

spop myset
12、点赞、签到、打卡

假如上面的微博ID是t1001,用户ID是u3001

用 like:t1001 来维护 t1001 这条微博的所有点赞用户

  • 点赞了这条微博:sadd like:t1001 u3001
  • 取消点赞:srem like:t1001 u3001
  • 是否点赞:sismember like:t1001 u3001
  • 点赞的所有用户:smembers like:t1001
  • 点赞数:scard like:t1001
13、商品标签

老规矩,用 tags:i5001 来维护商品所有的标签。

sadd tags:i5001 画面清晰细腻
sadd tags:i5001 真彩清晰显示屏
sadd tags:i5001 流程至极
14、商品筛选
// 获取差集
sdiff set1 set2
// 获取交集(intersection)
sinter set1 set2
// 获取并集
sunion set1 set2

假如:iPhone15 上市了

sadd brand:apple iPhone11
sadd brand:ios iPhone11
sad screensize:6.0-6.24 iPhone11
sad screentype:lcd iPhone 11

筛选商品,苹果的、ios的、屏幕在6.0-6.24之间的,屏幕材质是LCD屏幕

sinter brand:apple brand:ios screensize:6.0-6.24 screentype:lcd
15、用户关注、推荐模型

follow 关注 fans 粉丝

相互关注:

sadd 1:follow 2
sadd 2:fans 1
sadd 1:fans 2
sadd 2:follow 1

我关注的人也关注了他(取交集):

sinter 1:follow 2:fans

可能认识的人:

用户1可能认识的人(差集):sdiff 2:follow 1:follow
用户2可能认识的人:sdiff 1:follow 2:follow
16、排行榜

id 为6001 的新闻点击数加1:

zincrby hotNews:20190926 1 n6001

获取今天点击最多的15条:文章来源地址https://www.toymoban.com/news/detail-801116.html

zrevrange hotNews:20190926 0 15 withscores

go的incr+expire原子性操作之调用lua脚本

  • 它实现了 incr 和 expire 的原子化操作,并且在 key 不存在和 key 已经过期的情况下也能正常工作。
package main

import (
   "context"
   "fmt"
   "github.com/go-redis/redis/v8"
   "time"
)

// Lua脚本
// 通过执行一个 Lua 脚本来实现原子化的 incr 和 expire 操作。如果该 key 的过期时间已经设置为 -1,
// 则表示该 key 没有过期时间,此时通过 expire 命令为该 key 设置过期时间。
func main(){
   client := redis.NewClient(&redis.Options{
       Addr:     "localhost:6379",
       Password: "123456",
       DB:       10,
   })
   defer client.Close()

   result1, err1 := IncrWithTTL(client, "counter", 3600)
   if err1 != nil {
       fmt.Println(err1)
   } else {
       fmt.Println(result1)
   }
}

func IncrWithTTL(client *redis.Client, key string, ttl time.Duration) (int64, error) {
    script := redis.NewScript(`
    local value = redis.call("incr", KEYS[1])
                if redis.call("ttl", KEYS[1]) == -1 then
                redis.call("expire", KEYS[1], ARGV[1])
                end
                return value
    `)
    result, err := script.Run(context.Background(), client, []string{key}, ttl.String()).Result()
    if err != nil {
         return 0, err
    }
    return result.(int64), nil
}

到了这里,关于Go新项目-调研关于go项目中redis的使用场景,lua实战(7)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Go新项目-配置文件的选取及区别和写法(1)

    先说结论:我们选型TOML yaml,toml,json,ini 实际业务都有用 实际栗子是:我们想要把Go的切片作为配置文件,YAML写起来比较吃力,TOML就很容易了。 配置文件是用于配置计算机程序的参数、初始化设置的文件、业务数据公共配置等。如果没有这些配置,我们的程序就会硬编码

    2024年01月18日
    浏览(50)
  • Go新项目-Gin中wire的依赖注入方式实战(6)

    选型Go项目过程中,针对依赖注入方式的分析和使用 https://go.dev/blog/wire https://medium.com/@dche423/master-wire-cn-d57de86caa1b https://toutiao.io/posts/et0t2lk/preview https://imlht.com/archives/223/ https://lailin.xyz/post/go-training-week4-wire.html https://luenci.me/2022/01/08/%E8%81%8A%E8%81%8AWire%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%

    2024年01月18日
    浏览(50)
  • 如何使用Visual Studio创建第一个新项目

    第一步,打开Visual Studio进行创建新项目 这里可以选择空项目 在这里设置项目名称及位置(建议新建一个文件夹存放自己的代码) 在源文件里新建 新建源文件进行编写代码 这里可以选择文件类型设置名称 编写程序后,进行运行 如果没有错误的话,运行成功 到这里的话,你

    2024年02月12日
    浏览(73)
  • 如何使用Vue的ui界面创建一个新项目

    第一步: win+r打开命令提示符,然后输入cmd后回车。 第二步: 在命令行输入命令vue ui(中间有空格)后回车,弹出ui界面。 第三步: 点击创建,双击地址栏确定我们要保存框架的地址,回车确定该地址,然后点击下面的   第四步: 完成第三步进入以下界面: 依次输入项目名

    2024年02月05日
    浏览(68)
  • 编程语言:微软 Azure CTO 表示,是时候停止在新项目中使用 C 和 C++

    Azure CTO Mark Russinovich 说,业界应该将 C 和 C++ 语言视为“已弃用”。 Windows 11 22H2:如何获得微软最新的操作系统更新以及接下来会发生什么 Microsoft Azure 的首席技术官 Mark Russinovich 表示,出于安全性和可靠性的考虑,开发人员应避免在新项目中使用 C 或 C++ 编程语言,而应使用

    2024年02月06日
    浏览(56)
  • Gitlab 新项目搭建

    项目名称与本地新建项目名称相同 进入本地项目根目录下,右击 git bash here打开命令窗口; 初始化本地仓库; 提交至暂存区; 提交项目。 建立本地仓库和远端 Gitlab 仓库关系; 2.拉取一下远程仓库内容; 推送本地内容到远程仓库。 出现以下问题: 原因就是 Gitlab 的仓库中

    2024年02月13日
    浏览(68)
  • 新项目搞完啦!!!

    大家好,我是鱼皮。 经过了 7 场直播,总时长近 20 小时,我在 自己的编程导航 的第 5 个 全程直播开发 的项目 —— 智能 BI 项目,完结啦! 我在这里对该项目做一个简单的总结,希望让更多需要它的同学看到,把它变成自己的项目~ 这次做的是一个顺应潮流的项目, 基于

    2024年02月11日
    浏览(67)
  • 新项目如何推送Git

    一、在git新建一个空的仓库,不用任何模版,直接创建即可 完成后,copy仓库地址 二、本地新建项目,进入到本地项目命令行,也可以打开终端,其实是相通的:执行命令git init, 此时在项目上右击就发想有git选项,点击add添加,接着正常commit,然后push 在push的时候会发现有

    2024年02月12日
    浏览(69)
  • 笔记 | FastAPI创建新项目

    当使用FastAPI创建项目时,首先需要安装FastAPI和其依赖项。可以使用pip来安装它们。请确保已经安装了Python和pip。 创建项目文件夹并进入该文件夹: 创建并激活一个新的Python虚拟环境(可选,但强烈推荐): 安装FastAPI和uvicorn(FastAPI的服务器): 创建一个名为 main.py 的文件

    2024年02月06日
    浏览(66)
  • idea新项目上传git

    关于idea新项目怎么上传到git,今天整理一下操作的步骤。来做一个记录! 1.首先要在项目上右击打开终端或者在idea的下方有一个快捷按钮 按照上面的截图进行操作,打开终端窗口 2.然后在终端窗口中输入 git init 命令,会出现如图样子 3.然后右击项目会出现git的选项,然后按

    2024年02月12日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包