• redis分布式锁应用


    前提

    项目业务开发已完成,开始着手准备多节点拓展方案。

    项目使用go语言开发,gin框架。

    项目中使用了go原生的进程锁 sync.Mutex ,用于防止高并发下,数据可能遭到重复修改的问题。

    但是用了进程锁就无法支持集群部署架构,集群中每个单点都是一个进程,只能锁住自己的一部分,而操作的又是同一个DB,高并发下就会出现数据重复修改的问题。

    因此需要引入分布式锁,用来保证多节点部署架构下,数据正常。

    方案选择

    有多种分布式锁的方案,ZooKeeper,基于数据库实现分布式锁(for update),redis等。

    鉴于项目本身面对的用户量并不多,首期预计2000人,多节点方案也只是plan B,避免上线当天出现炸服的情况,有个方案可以及时拓展节点,提高承载量,

    因此最终选用了redis,简单易用,而且项目本身也部署了redis,也不影响现有的架构,毕竟多引入一个中间件,就多了其他的风险。

    redis分布式锁应用实例

    redis分布式锁,用的是其Setnx(SET if Not Exists)函数, 指定的 key 不存在时,为 key 设置指定的值。

    因为redis是单线程的,因此Setnx 100%是串行执行命令, 当多个请求进来时,即使同时调用Setnx,最终是按顺序返回值,达到了锁的效果。

    项目中使用示例:

    func main() {
        key := consts.USER_UPDATE + id
        op := ExistKeyOrSet(key, consts.DB_OP_EXPIRES_TIME)
    
        if !op {
    	// 已存在key,表示上一次操作未结束
    	appG.Response(http.StatusBadRequest, e.FREQUENT_OPERATION, nil)
    	return
        }
    
        // 程序执行结束后删除 redis 存储数据
        defer rdb.DelKey(key)
    }
    
    
    
    func ExistKeyOrSet(key string, expiresTime time.Duration) bool {
    	timestamp := time.Now().UnixNano()
    	// redis的setnx方法 key存在返回false, 不存在则设置锁并返回true
    	return Client.SetNX(ctx, key, timestamp, expiresTime).Val()
    }
    

      

  • 相关阅读:
    【剑指offer】面试题16、反转链表
    【剑指offer】面试题15、链表中倒数第 K 个结点
    【剑指offer】面试题14、调整数组顺序使奇数位于偶数前面
    oracle sql与调优
    linux 常用命令记录 持续更新
    函数重载中形参的const
    mem_fun_ref和mem_fun的用法
    c++风格的格式化输出
    count_if函数里面的第三个参数的书写方式<<0926
    操作符重载(++,+,输入输出,强制类型转换)
  • 原文地址:https://www.cnblogs.com/yourstars/p/16373417.html
Copyright © 2020-2023  润新知