七种方案对比分布式锁
前言日常开发中,秒杀下单、抢红包等等业务场景,都需要用到分布式锁。而Redis非常适合作为分布式锁使用。本文将分七个方案展开,跟大家探讨Redis分布式锁的正确使用方式。如果有不正确的地方,欢迎大家指出哈,一起学习一起进步。
公众号:捡田螺的小男孩
什么是分布式锁
方案一:SETNX + EXPIRE
方案二:SETNX + value值是(系统时间+过期时间)
方案三:使用Lua脚本(包含SETNX + EXPIRE两条指令)
方案四:SET的扩展命令(SET EX PX NX)
方案五:SET EX PX NX + 校验唯一随机值,再释放锁
方案六: 开源框架:Redisson
方案七:多机实现的分布式锁Redlock
github地址,感谢每颗star
https://github.com/whx123/JavaHome
什么是分布式锁
分布式锁其实就是,控制分布式系统不同进程共同访问共享资源的一种锁的实现。如果不同的系统或同一个系统的不同主机之间共享了某个临界资源,往往需要互斥来防止彼此干扰,以保证一致性。
我们先来看下,一把靠谱的分布式锁应该有哪 ...
程序员必备基础:Git 命令全方位学习
前言掌握Git命令是每位程序员必备的基础,之前一直是用smartGit工具,直到看到大佬们都是在用Git命令操作的,回想一下,发现有些Git命令我都忘记了,于是写了这篇博文,复习一下~
https://github.com/whx123/JavaHome
公众号:捡田螺的小男孩
文章目录
Git是什么?
Git的相关理论基础
日常开发中,Git的基本常用命令
Git进阶之分支处理
Git进阶之处理冲突
Git进阶之撤销与回退
Git进阶之标签tag
Git其他一些经典命令
Git是什么在回忆Git是什么的话,我们先来复习这几个概念哈~
什么是版本控制?百度百科定义是酱紫的~
版本控制是指对软件开发过程中各种程序代码、配置文件及说明文档等文件变更的管理,是软件配置管理的核心思想之一。
那些年,我们的毕业论文,其实就是版本变更的真实写照…脑洞一下,版本控制就是这些论文变更的管理~
什么是集中化的版本控制系统?那么,集中化的版本控制系统又是什么呢,说白了,就是有一个集中管理的中央服务器,保存着所有文件的修改历史版本,而协同开发者通过客户端连接到这台服务器,从服务器上同步更新或上传 ...
学习Redis相关知识
前言最近在学习Redis相关知识,看了阿里的redis开发规范,以及Redis开发与运维这本书。分使用规范、有坑的命令、项目实战操作、运维配置四个方向。整理了使用Redis的21个注意点,希望对大家有帮助,一起学习哈
1、Redis的使用规范1.1、 key的规范要点我们设计Redis的key的时候,要注意以下这几个点:
以业务名为key前缀,用冒号隔开,以防止key冲突覆盖。如,live:rank:1
确保key的语义清晰的情况下,key的长度尽量小于30个字符。
key禁止包含特殊字符,如空格、换行、单双引号以及其他转义字符。
Redis的key尽量设置ttl,以保证不使用的Key能被及时清理或淘汰。
1.2、value的规范要点Redis的value值不可以随意设置的哦。
第一点,如果大量存储bigKey是会有问题的,会导致慢查询,内存增长过快等等。
如果是String类型,单个value大小控制10k以内。
如果是hash、list、set、zset类型,元素个数一般不超过5000。
第二点,要选择适合的数据类型。不少小伙伴只用Redis的String类型,上来 ...
线程池运用不当导致的问题
在高并发、异步化等场景,线程池的运用可以说无处不在。线程池从本质上来讲,即通过空间换取时间,因为线程的创建和销毁都是要消耗资源和时间的,对于大量使用线程的场景,使用池化管理可以延迟线程的销毁,大大提高单个线程的复用能力,进一步提升整体性能。
今天遇到了一个比较典型的线上问题,刚好和线程池有关,另外涉及到死锁、jstack命令的使用、JDK不同线程池的适合场景等知识点,同时整个调查思路可以借鉴,特此记录和分享一下。
01 业务背景描述该线上问题发生在广告系统的核心扣费服务,首先简单交代下大致的业务流程,方便理解问题。
绿框部分即扣费服务在广告召回扣费流程中所处的位置,简单理解:当用户点击一个广告后,会从C端发起一次实时扣费请求(CPC,按点击扣费模式),扣费服务则承接了该动作的核心业务逻辑:包括执行反作弊策略、创建扣费记录、click日志埋点等。
问题现象和业务影响12月2号晚上11点左右,我们收到了一个线上告警通知:扣费服务的线程池任务队列大小远远超出了设定阈值,而且队列大小随着时间推移还在持续变大。详细告警内容如下:
相应的,我们的广告指标:点击数、收入等也出现了非常明显的下滑,几乎 ...
记一次接口性能优化实践总结:优化接口性能的八个建议
前言最近对外接口偶现504超时问题,真枪实弹搞了一次接口性能优化。在这里结合优化过程,总结了接口优化的八个要点,希望对大家有帮助呀~
数据量比较大,批量操作数据入库
耗时操作考虑异步处理
恰当使用缓存
优化程序逻辑、代码
SQL优化
压缩传输内容
考虑使用文件/MQ等其他方式暂存,异步再落地DB
跟产品讨论需求最恰当,最舒服的实现方式
嘻嘻,先看一下我们对外转账接口的大概流程吧
1. 数据量比较大,批量操作数据入库批量插入优化方法应该是我们最容易想到的啦~
优化前
1234//for循环单笔入库for(TransDetail detail:list){ insert(detail); }
优化后
123456789// 批量入库,mybatis demo实现<insert id="insertBatch" parameterType="java.util.List"> insert into trans_detail( id,amount,payer,payee) values <fore ...
金三银四,给面试者的十大建议
一、提前复习好你的专业知识专业知识是最为重要的一点,拥有了坚实的专业基础,你才能迈向成功的彼岸。
因此,面试之前,一定一定要复习好专业知识。对自己学过的知识,要做一个概括,放在脑海中。茶余饭后,复习一下,做到随便看到一道基础题目,心中都能有个答案。
比如,一道最基本基础题,ArrayList和LinkedList有什么区别?如果你是做Java后台开发的,应该都会了吧,哈哈,不会的赶紧复习一下,哈哈哈。
所以,面试前还是像图下这位小伙子一样,好好复习,哈哈~
二、对简历上写的项目一定要足够了解,把握其中的亮点。你在简历上的信息,就是面试官了解你的窗口。你写上去的项目,自己一定一定要了解清楚来龙去脉。如果把别人很厉害的项目copy上去,面试官一问你三不知,那就露馅啦~
同时,简历上需要沉淀一些有内容的东西,需要有些亮点。当然,简历上的亮点并不一定是酝酿百年的女儿红,也可以是你自己含辛茹苦酿造出的米酒,只要有你汗水的味道体现在里面就可以啦。
也就是说,你的简历不一定就需要是github上几百star的项目,也可以是你自己负责设计的一些有意思的项目,甚至一个小小的挂号系统,只要你能在里面,倾注 ...
Mysql死锁问题分析
前言遇到Mysql死锁问题,我们应该怎么排查分析呢?之前线上出现一个insert on duplicate死锁问题,本文将基于这个死锁问题,分享排查分析过程,希望对大家有帮助。
死锁案发还原表结构: 1234567CREATE TABLE `song_rank` ( `id` int(11) NOT NULL AUTO_INCREMENT, `songId` int(11) NOT NULL, `weight` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `songId_idx` (`songId`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8;隔离级别:
1234567mysql> select @@tx_isolation;+-----------------+| @@tx_isolation |+-----------------+| REPEATABLE-READ |+-----------------+1 r ...
数据库连接池内存泄漏问题分析
一、问题描述上周五晚上主营出现部分设备掉线,经过查看日志发现是由于缓存系统出现长时间gc导致的。这里的gc日志的特点是:
1.gc时间都在2s以上,部分节点甚至出现12s超长时间gc。
2.同一个节点距离上次gc时间间隔为普遍为13~15天。
然后紧急把剩余未gc的一个节点内存dump下来,使用mat工具打开发现,com.mysql.jdbc.NonRegisteringDriver 对象占了堆内存的大部分空间。
查看对象数量,发现com.mysql.jdbc.NonRegisteringDriver$ConnectionPhantomReference 这个对象堆积了10140 个。
初步判断长时间gc的问题应该是由于 com.mysql.jdbc.NonRegisteringDriver$ConnectionPhantomReference 这个对象大量堆积引起的。
二、问题分析目前正式环境使用数据库相关依赖如下:
依赖
版本
mysql
5.1.47
hikari
2.7.9
Sharding-jdbc
3.1.0
根据以上描述,提出以下问题:
1、 ...
日常工作中最容易犯的几个并发错误
前言列举大家平时在工作中最容易犯的几个并发错误,都是在实际项目代码中看到的鲜活例子,希望对大家有帮助。
First Blood线上总是出现:**ERROR 1062 (23000) Duplicate entry ‘xxx’ for key ‘yyy’**,我们来看一下有问题的这段代码:
12345678UserBindInfo info = selectFromDB(userId);if(info == null){ info = new UserBindInfo(userId,deviceId); insertIntoDB(info);}else{ info.setDeviceId(deviceId); updateDB(info); }
在并发情况下,第一步判断都为空,就会有2个或者多个线程进入插入数据库操作,这时候就出现了同一个ID插入多次。
正确处理姿势:
1insert into UserBindInfo values(#{userId},#{deviceId}) on duplicate ke ...
并发环境下,先操作数据库还是先操作缓存?
前言在分布式系统中,缓存和数据库同时存在时,如果有写操作的时候,先操作数据库还是先操作缓存呢?先思考一下,可能会存在哪些问题,再往下看。下面我分几种方案阐述。
缓存维护方案一假设有一写(线程A)一读(线程B)操作,先操作缓存,在操作数据库。,如下流程图所示:
1)线程A发起一个写操作,第一步del cache
2)线程A第二步写入新数据到DB
3)线程B发起一个读操作,cache miss,
4)线程B从DB获取最新数据
5)请求B同时set cache
这样看,没啥问题。我们再看第二个流程图,如下:
1)线程A发起一个写操作,第一步del cache
2)此时线程B发起一个读操作,cache miss
3)线程B继续读DB,读出来一个老数据
4)然后老数据入cache
5)线程A写入了最新的数据
OK,酱紫,就有问题了吧,老数据入到缓存了,每次读都是老数据啦,缓存与数据与数据库数据不一致。
缓存维护方案二双写操作,先操作缓存,在操作数据库。
1)线程A发起一个写操作,第一步set cache
2)线程A第二步写入新数据到DB
3)线程B发起一个写操作,set cache,
4)线 ...