-
Redis分布式锁实现指北 TOP NEW
背景 分布式锁在业务场景中的应用十分广泛,当你的服务部署在分布式的多节点集群中,在执行某一个方法时,需要控制并发的情况,保证同一时间只有一个请求可以执行,你一定需要分布式锁来实现。 最常见的分布式锁,一般就是Redis和ZK(亦或者MySQL的for update也可以充当),当然也有很多其他的实现,本篇的主角,就是Redis,我们来逐步使用实现一个简单易用的Redis分布式锁。 RedisLock 首先,我们先来回忆一下Java的Lock是怎么玩的: ReentrantLock lock = new ReentrantLock(); try { lock.lock(); // do something... } finally { lock.un... Read More
-
记一次业务MySQL死锁 TOP NEW
问题 线上服务出现服务告警,查询日志现场,错误信息如下: Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:124) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMappin... Read More
-
Protobuf Varint序列化原理 TOP NEW
前言 Protocol Buffers(简称 protobuf)使用 varint(可变长整数)格式来序列化一些整数类型(如 int32, int64, uint32, uint64 等)。varint 的基本原理是将整数按照字节进行分段编码,以尽可能节省存储空间。这种编码方式使得对于较小的整数值,占用的字节数非常少,而对于较大的整数,则会根据需要动态增加字节。 Varint 序列化的工作原理 字节按位拆分:Protobuf 将整数值分解为一组 7 位的块(字节),每个字节保存一个 7 位的数据 高位标记:每个字节的最高位(第 8 位)是一个标志位,用于指示该字节是否是最后一个字节。具体地: 如果字节的最高位为 1,表示该字节之后还有更多字节(即这个字节不是最后一个... Read More
-
亿级排行榜设计 TOP NEW
问题 假如有10亿的用户,每个用户有自己的分数(score),请你设计一个排行榜,可以根据用户的分数进行排名,每个用户可以知道自己在排行榜中的排名情况。 分析 一说到排行榜,我们的第一反应肯定是使用Redis的ZSET结构实现,那么使用ZSET如何实现对10亿用户进行排序? ZSET单key 第一种思路,使用ZSET单key,也就是将10亿用户都放入一个ZSET key中,简单明了,这样设计是最简单的,但查询的性能是否可以接受?我们来计算一下: ZSET结构使用SkipList实现,查询的时间复杂度:ZREVRANK:O(log(N)) 查询单个排名的理论时间复杂度:O(log(10^9)) ≈ 30次比较 内存占用分析: public class Perform... Read More
-
MySQL为什么有了redolog还需要double write buffer TOP NEW
问题 我们知道MySQL InnoDB引擎使用redolog作为异常容灾恢复的机制,当MySQL进程发生异常退出、机器断电等,在重新启动时,使用redolog恢复。 OK,redolog是被MySQL设计为异常崩溃恢复的,double write buffer同样是为了保证数据完整性,那么既然已经有了redolog,为什么还需要double write buffer(双写缓冲区)呢? double write buffer InnoDB用double write buffer(双写缓冲区)来避免页没写完整所导致的数据损坏。当一个磁盘写操作不能完整地完成时,不完整的页写入就可能发生,16KB的页可能只有一部分被写到磁盘上。有多种多样的原因(崩溃、Bug,等等)可能导致页没有写... Read More
-
Java ThreadPoolExecutor线程池概述 TOP NEW
-
MySQL慢SQL探究 TOP NEW
前言 我们在日常开发中,一定遇见过某些SQL执行较慢的情况,我们俗称“慢SQL”,如果你对系统的接口性能要求较高的话,一定不会放过这种SQL,肯定会想办法进行解决,那么,导致慢SQL出现的原因,究竟可能都有哪些呢? 这是一道经典的面试题,就此我们来研究一番,下面,我们就来好好看一下,原因可能出在哪里。 本篇我们将从如下几个方面进行讨论: 1、慢SQL捕获 2、执行计划分析 3、引擎参数配置分析 让我们就此开启本次慢SQL分析之旅,Let’s go! ps: 本篇文章的讨论,主要基于MySQL8.0数据库,Oracle等其他数据库不在本篇讨论范围之列。 1、慢SQL捕获 追查应用服务的慢SQL,首先需要追踪哪些SQL可能是慢SQL,对于Java服务,很多数... Read More
-
MySQL主键自增有几种模式? TOP NEW
前言 在大多数的业务场景下,我们的数据表的一般会默认使用主键自增长(AUTO_INCREMENT)模式,在执行insert语句时,MySQL会自动为数据行生成主键ID,保证其单调递增和不重复的。一般情况下,我们很少会关注AUTO_INCREMENT的策略模型,事实上,InnoDB提供了一个可配置的自增长模型机制,可以显著提高向带有AUTO_INCREMENT列的表添加记录的SQL语句的可扩展性和性能。 本篇,我们就来简要了解一下MySQL InnoDB的主键自增长策略模式。 INSERT种类 MySQL将INSERT操作分为三类: 1、Simple inserts 插入的记录行数是可以事先确定的。包括最常见的单条INSERT、REPLACE,但不包括INSERT ...... Read More
-
Redis key过期删除机制 TOP NEW
前言 当我们创建Redis key时,可以通过expire命令指定key的过期时间(TTL),当超过指定的TTL时间后,key将会失效。 那么当key失效后,Redis会立刻将其删除么?如果不会,那么何时Redis才将其真正的删除呢?我们来一起一探究竟。 Redis key过期淘汰机制 Redis中的key过期淘汰机制是由两种方式实现: 惰性删除机制 定时扫描删除机制 两种模式都不会在key达到过期时间后,第一时间删除key,而是等待特定的时机触发淘汰机制,这个很好理解,如果每一个key到达过期时间后,redis都需要第一时间检测到,并将其删除,那么将会消耗大量的资源,去实时的扫描全部key值,这显然是不合理的。 下面我们来看一下两种方式的具体实现机制。 ... Read More
-
Redis6.0 Client-Side缓存是什么 TOP NEW