自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(85)
  • 收藏
  • 关注

原创 mysql如何排查死锁问题

MySQL默认的处理方式是自动检测到死锁后,其中一个事务会被选择为"牺牲者"并回滚,以解除死锁。被选择的事务会收到一个Deadlock Detected异常,然后回滚该事务,释放相关的资源,允许其他事务继续执行。当死锁发生时,MySQL会选择其中一个事务进行回滚,以解除死锁,并且会记录相关的死锁信息,可通过查看错误日志或使用SHOW ENGINE INNODB STATUS命令来获取死锁信息。可以分析得出被死锁具体的表和sql语句了, 解决通过查看具体的线程id,kill 掉,手动去补偿数据。

2024-07-18 20:28:41 287

原创 幂等的时候依赖数据库的唯一索引,如果使用的是主从数据库,同步有延迟的情况下,会有影响吗?

如果单纯对一个数据库进行select,仅仅考虑select的话,select天然具有幂等性。但是如果涉及主从同步的话,就会存在幂等性的问题:用户第一次下单,先从从库查,没有,在主库中插入一条订单,此时用户手抖再次下单,从从库查(但是主库还没来得及同步从库)没有,用户重复下单成功,导致出了问题,如果关键读从主库读就不会有问题了。

2024-07-17 22:04:07 196

原创 分布式事务Seata AT 详解

2. 本地事务为什么在一阶段提交:为了提高性能,AT模式基于2PC的,但2PC的一阶段并不会真正提交本地事务,也就意味着一直持有资源不释放,性能较差,但AT模式在一阶段提交了本地事务,其他本地事务就可以执行,但全局锁还没有释放,同时还有undolog image的记录,来保证后续有异常仍然能够进行事务回滚,提高性能。4. AT模式的隔离级别:读未提交,因为当一阶段本地事务提交之后,其他的分布式事务已经可以看到提交后的数据,但因为有全局锁的存在,此时全局锁还没有释放,只能读到数据不能写数据。

2024-07-08 19:31:45 521 1

原创 volatile和static的区别

强制线程每次读取时都从主内存中获取,每次写入时都写入主内存,确保变量的可见性。仅用于声明变量,确保在多线程环境中的可见性,使所有线程都能看到最新的变量值。通过保证变量的可见性,提供了一定的线程安全保障。它还可以用于方法、初始化块和内部类。变量在内存中有一个存储位置,所有实例共享这一个存储位置。关键字用于创建类级别的变量或方法,所有类的实例共享同一个。不保证原子性,因此在复杂操作中可能不足以保证线程安全。由于所有实例共享一个变量副本,因此性能较高。可能影响性能,因为每次读写都需要访问主内存。

2024-07-08 19:25:53 493

原创 使用redis分布式锁,不要把锁放在本地事务内部

在使用分布式锁的时候,习惯性的尽量缩小同步代码块的范围。但是如果数据库隔离级别是可重复读,这种情况下不要把分布式锁加在@Transactional注解的事务方法内部。因为可能会出现这种情况:

2024-07-04 21:29:20 345

原创 Redis分布式锁的应用场景有哪些

在多线程并发的场景下,JavaSynchronized/Reentrantlock锁能够实现同⼀个JVM进程内多线程并发的安全性,但⽆法保证多个JVM进程实例构成的集群环境在多线程下的安全性。在⼀些业务场景下需要引⼊分布式锁。

2024-07-03 19:52:30 553

原创 Redis如何实现主从复制

发生在初始化阶段,从节点会主动向主节点发出一个同步请求,之后主节点会生成一份当前数据的快照给从节点,从节点在收到数据进行加载后,会完成全量复制。主是主服务器,从是从服务器,主服务器(master )的数据如果更新了也会同步到从服务器(slave),一个主服务器可以搭配很多个从服务器,,每一次Master(主)结点发生数据变更之后,会把变化的增量数据同步给从节点,增量复制是通过维护offset复制偏移量来实现的。Redis主从复制包括。

2024-07-02 22:08:00 781

原创 CAP原理---最终一致性

当客户端在Redis的主节点修改了数据后,立即返回,即使在主从网络断开的情况下,主节点依旧可以正常对外提供修改服务,所以Redis满足「可用性」。,最终从节点的状态会和主节点的状态将保持一致。在网络分区发生时,两个分布式节点之间无法进行通信,我们对一个节点进行的修改操作将无法同步到另外一个节点,所以数据的「一致性」将无法满足,因为两个分布式节点的数据不再保持一致。分布式系统的节点往往都是分布在不同的机器上进行网络隔离开的,这意味着必然会有网络断开的风险,这个网络断开的场景的专业词汇叫着「网络分区」。

2024-07-02 22:06:29 440

原创 为什么要有redo log

就是说,虽然binlog里面会针对于一个事务里的sql进行完整的记录也会记录事务的开启提交状态,但是呢这都是逻辑层面的,比如说记录一条sql (statement格式),比如说记录xx行数据+1,xx行数据-1(row格式),但是我们思考一个问题,mysql真实的数据存储是通过数据页的形式记录在磁盘的,也就是说,一个事务涉及到很多sql,一条sql语句可能涉及到很多数据页的变更,只通过binlog我们是无法判断一个事务的修改到底有没有真正落实到磁盘上的,为什么呢?一定是和正确答案一字不落的吗?

2024-07-01 21:50:53 368

原创 token的原理,机制

token其实也是一样的,是当客户端第一次发起请求时,服务器通过签名生成的一连串字符串,这个字符串只有服务器自己明白什么意思,别的人拿到也是一头雾水,甚至连客户端自己都不知道是什么意思。客户端再次发送请求时,一般会将token发在自己的请求头中,服务端收到请求后,会先去验证客户端发送的token是否与自己签发的token一致,如果一致则响应请求,如果不一致则拒绝请求。当然如果你如果只想做个系统自娱自乐,我就自己用,并不想让别用,那么通过数据库查询的方式完全是可以的,但是,一个公司做个项目不可能自娱自乐吧?

2024-07-01 21:48:10 426

原创 说一说强、软、弱、虚引用

唯一作用就是配合引用队列来监控引用的对象是否被加入到引用队列中,也就是可以准确的让我们知晓对象何时被回收。,也就是说在JVM抛出OutOfMemoryError之前,会去清理软引用对象,适合用在内存敏感的场景。,ThreadLocal中的 key 就用到了弱引用,适合用在内存敏感的场景。Java根据其生命周期的长短将引用类型又分为强引用、软引用、弱引用、虚引用。虚引用:如果一个对象仅持有虚引用,它就和没有任何引用一样,强引用:就是我们平时 new一个对象的引用。弱引用:比软引用还短,在GC的时候,

2024-06-24 20:58:20 341

原创 类加载机制

总体来说,Java程序的启动涉及了类加载、链接、初始化等多个步骤。当你运行Java程序时,Java虚拟机(JVM)会加载字节码文件。JVM通过类加载器(Class Loader)来加载字节码文件,将其转换为运行时的Java类。JVM会在加载和初始化完主类后寻找main方法,main方法是Java程序的入口点。一旦main方法被找到,JVM会执行main方法中的代码,从而启动Java程序的执行。在链接阶段,JVM将加载的类与它们引用的其他类和库进行链接。编译成功后,将在相同的目录中生成字节码文件。

2024-06-24 20:55:56 404

原创 为什么通过唯一索引给数据加锁,主键索引也会被锁住?

因此我们通过索引查找数据数据实际上是在索引的B+树中先找到对应的主键,然后根据主键再去主键索引的B+树的叶子结点中找到完整数据,最后返回。所以虽然是两个索引树,但实际上是同一行数据,必须全部锁住。索引还是普通索引,它们的叶子结点中存储的数据都不完整,其中只是存储了作为索引并且排序好的列数据以及对应的主键值。列的唯一索引,最终定位到主键值为。的数据,最终拿到完整的行数据。对数据进行查询,会先用到。,然后再到主键索引中查询。

2024-06-17 21:15:40 313

原创 Broker和NameServer的心跳机制

然后NameServer会每隔10s运行一个任务,去检查一下各个Broker的最近一次心跳时间,如果某个Broker超过120s都没发送心跳了,那么就认为这个Broker已经挂掉了。Broker会每隔30s给所有的NameServer发送心跳,告诉每个NameServer自己目前还活着。Broker会跟每个NameServer都建立一个TCP长连接,然后定时通过TCP长连接发送心跳请求过去。

2024-06-12 22:30:49 227

原创 RocketMQ事务性消息

(4)发送方根据本地事务执行结果向服务端提交二次确认(Commit 或是 Rollback),服务端收到Commit 状态则将半事务消息标记为可投递,订阅方最终将收到该消息;由于消息为半事务消息,在未收到生产者对该消息的二次确认前,此消息被标记成“暂不能投递”状态。(1)在断网或者是应用重启的特殊情况下,上述步骤4提交的二次确认最终未到达服务端,经过固定时间后服务端将对该消息发起消息回查。(3) 发送方根据检查得到的本地事务的最终状态再次提交二次确认,服务端仍按照步骤4对半事务消息进行操作。

2024-06-12 22:26:54 375

原创 mysql的双写一致性

加锁(400 ms) 超时直接放弃 并发先读后写场景 必须要加锁 为什么超时直接放弃?---》假设整个流程要300ms,总不能一直干耗着,后面的线程就不用来走这个逻辑了。查redis没有才继续往下 double check(单例模式)

2024-06-07 20:51:06 275

原创 Bean的作用域

(仅 Web 应用可用) : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效。(仅 Web 应用可用): 每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。,每次获取都会创建一个新的 bean 实例。两次,得到的是不同的 Bean 实例。

2024-06-07 20:49:34 480

原创 什么是PLAB?

先从老年代 freelist(空闲链表)申请一块空间,然后在这一块空间中就可以通过指针加法(bump thepointer)来分配内存,这样对freelist竞争也少了,分配空间也快了。可以看到和TLAB很像,PLAB即 Promotion Local Allocation Buffers。大致就是上图这么个思想,每个线程先申请一块作为PLAB,然后在这一块内存里面分配晋升的对象。在多线程并行执行YGC时,可能有很多对象需要晋升到老年代,此时老年代的指针就"热"起来了,于是搞了个PLAB。

2024-06-01 21:31:40 533

原创 什么是TLAB?

在HotSpot 中会生成一个填充对象来填满这一块,因为堆需要线性遍历,遍历的流程是通过对象头得知对象的大小,然后跳过这个大小就能找到下一个对象,所以不能有空洞。TLAB的思想其实很简单,就是划一块区域给一个线程,这样每个线程只需要在自己的那亩地申请对象内存,不需要争抢热点指针。一般而言生成对象需要向堆中的新生代申请内存空间,而堆又是全局共享的,像新生代内存又是规整的,是通过一个指针来划分的。可以看到TLAB内部只剩一格大小,申请的对象需要两格,这时候需要再申请一块TLAB,之前的那一格就浪费了。

2024-06-01 21:30:12 271

原创 JVM哪些区域可能出现内存溢出,哪些地方需要GC?

需要GC:方法区在Java 8之后使用Metaspace取代了永久代,它具有更灵活的内存管理机制,不再有永久代的限制。- 可能出现内存溢出:栈用于存储**线程的方法调用**和**局部变量**,当栈空间不足时可能导致栈溢出。,所以思考一下,沿着之前提到过的JVM内存分区,堆,栈,程序计数器,方法区。* 可能出现内存溢出:堆是存储对象实例的区域,当创建的对象数量超过堆的容量时,就会导致堆内存溢出。- GC:程序计数器不涉及垃圾回收。- GC:主要的垃圾回收工作发生在堆中,回收无用的对象,释放内存空间。

2024-05-31 21:51:48 589

原创 多线程,对于批量更新数据库表中同一行的a、b、c属性造成的死锁该如何解决

综上所述,解决多线程批量更新数据库表中同一行的属性造成的死锁问题需要从多个方面入手,包括拆分批量更新、使用锁机制、调整事务隔离级别、优化数据库索引、控制并发量、实现重试机制以及加强监控和日志记录等。这些策略可以根据实际情况进行灵活组合和调整,以达到最佳的性能和一致性平衡。

2024-05-31 19:51:59 520

原创 RocketMQ中Topic、MessageQueue以及Broker之间到底是什么关系?

比如你现在有一个Topic,我们为他指定创建了4个MessageQueue,那么我们接着来思考一下,这个Topic的数据在Broker集群中是如何分布的?假如我们现在集群有两个master-broker一个master对应两个slave。通过这个方法,就可以实现Topic数据的分布式存储!

2024-05-30 22:01:31 493

原创 RocketMQ重复消费的幂等性问题

----》重复消费根部避免不了。只能从消息的幂等消费入手。----》多次调用接口,得到的结果都一样。

2024-05-30 21:59:23 540

原创 RocketMQ如何保证消息不丢失

再反馈会Broker说消费成功,这样才可以保证消费阶段不丢消息。有些业务场景为了快速消费数据就拿到消息后直接返回成功,但是有可能消费数据失败,那这条数据对下游来说就等于丢失了。存储消息的过程,先存到内存page cache,再持久化到磁盘,默认配置是直接到内存后就返回成功了,但是如果这时候机器断电了,就会丢失消息,需要配置成落磁盘后再返回成功。,那为什么还会有异步,因为异步发送效率高。

2024-05-27 21:47:43 331

原创 RocketMQ如何保证顺序消费

以订单为例,将不同的订单分配到不同的queue中,让某一个订单的消息固定分配到一个queue中,可以采用固定的订单号hash然后对queue长度取模,这样每个订单的消息就按顺序发送了,还必须要保证下游单线程消费数据,如果是多线程的话,会出现和之前一样类似的问题,多线程不能按照预想的顺序去消费。topic可能分为多个queue,那queue的分配是随机的,不同queue之间的消费速率不一样,所以可能导致履约成功的消息最先到下游。业务场景需要,比如一个订单的流程,从创建到支付到发货到评价,需要按照顺序进行。

2024-05-27 21:46:55 766

原创 什么是MessageQueue(RocketMQ中的队列)

在RocketMQ中,MessageQueue是消息的物理存储单元,用于划分和管理消息的存储和消费。每个Topic都会被划分为多个MessageQueue,消息会按照一定的规则分配到不同的MessageQueue中。具体来说,RocketMQ的MessageQueue具有以下特点:1.唯一标识:每个MessageQueue都有一个唯一标识符,由Topic名称和队列编号组成。2.消息顺序性:对于同一个MessageQueue中的消息,RocketMQ保证其消费的顺序性,即先进先出(FIFO)。

2024-05-21 22:35:54 655

原创 Broker的主从架构

为了保证MQ的数据不丢失而且具备一定的高可用性,所以一般都是得将Broker部署成Master-Slave模式的,也就是—个Master Broker对应一个Slave Broker Master需要在接收到消息之后,将数据同步给Slave,这样一旦Master Broker挂了,还有Slave上有一份数据。Master上有全量数据,但是去Master上消费,Master压力会很大,但去Slave上去读,数据不全,但是很快。那RocketMQ如何取舍?---》当然是两者相结合。

2024-05-21 22:33:57 2281

原创 RocketMQ消息发送模式

异步发送是指发送方发出一条消息后,不等服务端返回响应,接着发送下一条消息的通讯方式。2.异步发送:在异步发送模式下,消息发送方发送消息后不会等待Broker的确认响应,而是立即返回并继续执行后续的代码逻辑。1.同步发送:在同步发送模式下,消息发送方会一直等待消息发送的结果返回。3.在单向发送模式下,消息发送方只发送消息,并不等待Broker的确认响应,也没有回调函数执行相应逻辑。此方式发送消息的过程耗时非常短,一般在微秒级别。RocketMQ提供了三种消息发送模式:同步发送,异步发送,单向发送。

2024-05-20 21:40:28 477

原创 什么是Topic

标识消息分类: RocketMQ的主题用于。通过为不同类型的消息分配不同的主题,可以使消息更具可读性和可管理性。独立的消息队列:每个主题都有自己的消息队列,用于存储该主题下的消息。每个队列都可以并行地接收和处理消息,从而实现高吞吐量和负载均衡。消息路由:生产者在发送消息时指定目标主题,消费者则通过订阅感兴趣的主题来接收对应的消息。RocketMQ根据主题将消息路由到相应的队列上,然后再由消费者消费。

2024-05-20 21:23:05 396

原创 Redis和Memcached的区别

能够提供高可用服务。Memcached 没有提供原生的集群模式,需要依靠客户端实现往集群中分片写入数据。value值大小不同: Redis最大可以达到512M;memcache只有1mb。,Memcached使用多线程的非阻塞IO模型。(Redis6.0引入了。MemCached 数据结构单一,仅用来缓存数据,而。MemCached不支持数据持久化,重启后数据会消失。

2024-05-17 20:54:13 343

原创 redission分布式锁框架

如果Redis提供了主从集群,当我们向集群写数据时,主机需要异步的将数据同步给从机,而万一在同步过去之前,主机宕机了,就会出现死锁问题。概率低,同步是毫秒级.看门狗机制,锁续期,可以用来解决锁提前释放的问题,默认30s过期,每10s检查一次,如果发现业务代码还在执行,后台线程就主动续约。redission框架出来的时间较早,功能比较完善 先入为主。不能多次获取同一把锁。可重入锁的意义是在于防止死锁。线程在获取锁失败后,应该能多次尝试。业务还没执行完,锁就释放了。trylock可重试。

2024-05-17 20:44:02 250

原创 Redis如何实现持久化

AOF(append only file)持久化:以独立日志的方式记录每次写命令,Redis重启时会重新执行AOF文件中的命令达到恢复数据的目的。通过RDB方式的持久化,一旦Redis异常退出,就会丢失最近一次持久化以后更改的数据。b. RDB文件使用特定二进制格式保存,Redis版本升级过程中有多个格式的RDB版本,存在老版本Redis 无法兼容新版RDB格式的问题。a. AOF可以更好的保护数据不丢失,可以配置AOF每秒执行一次fsync操作,如果Redis进程挂掉,最多丢失1秒的数据。

2024-05-15 22:30:06 609

原创 Redis事务

事务中如果有命令执行失败的话,其他命令仍然会被执行,不支持回滚。-----》那如何保证Redis的原子性操作,可以使用。,因为他在执行命令时是单线程的,事务在执行过程中不会被中断。

2024-05-15 21:37:07 187

原创 Redis哨兵机制

这时如果要恢复服务的话,需要人工介入,选择一个「从节点」切换为「主节点」,然后让其他从节点指向新的主节点,同时还需要通知上游那些连接 Redis 主节点的客户端,将其配置中的主节点 IP 地址更新为「新主节点」的 IP 地址。这样也不太“智能”了,要是有一个节点能监控「主节点」的状态,当发现主节点挂了,它自动将一个「从节点」切换为「主节点」的话,那么可以节省我们很多事情啊!它会监测主节点是否存活,如果发现主节点挂了,它就会选举一个从节点切换为主节点,并且把新主节点的相关信息通知给从节点和客户端。

2024-05-14 22:07:05 716

原创 Redis缓存降级

当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。c.错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;5.错误降级:当Redis 缓存出现故障或异常时,返回默认值或友好提示,而不是抛出错误,确保对用户透明且不影响系统的整体功能。2.降低缓存优先级:降低 Redis 缓存的优先级,让部分请求直接绕过缓存访问数据源,减轻Redis的负担。

2024-05-14 22:05:15 696

原创 基于Redis实现分布式锁

基于这个场景,我们可以发现,问题关键在于,竞争者可以释放其他人的锁。那么在异常情况下,就会出现问题,所以我们可以进一步给出解决方案:分布式锁需要满足谁申请谁释放原则,不能释放别人的锁,也就是说,分布式锁,是要有归属的。今天,就让我们从最基础的步骤开始,依照分布式锁的特性,层层递进,步步完善,将它优化到最优,让大家完整地了解如何用Redis来实现一个分布式锁。今天,就让我们从最基础的步骤开始,依照分布式锁的特性,层层递进,步步完善,将它优化到最优,让大家完整地了解如何用Redis来实现一个分布式锁。

2024-05-13 22:30:34 500

原创 Redis和Mysql 如何保证一致性

把我们搭建的消费服务作为mysql的一个slave,订阅mysql的bin log日志,解析日志内容,再更新到redis。不光通过key的过期时间兜底,还需要在更新mysql时,同时尝试操作redis,这里的操作分两种方式,1是更新,直接将结果写入Redis,使用redis的过期时间,mysql更新时,redis不做处理,等待缓存过期失效,再从mysql拉取缓存。- 通常来说,过期时间兜底是行之有效的办法,根据实时性期待不一样,可以增加个删除逻辑,提升一致性。- 更新MySQL之后,操作Redis。

2024-05-13 20:50:23 833

原创 Redis如何进行内存管理的?---过期删除策略和内存淘汰策略

在设置某个key 的过期时间同时,我们创建一个定时器,让定时器在该过期时间到来时,立即执行对其进行删除的操作。优点:定时删除对内存是最友好的,能够保存内存的key一旦过期就能立即从内存中删除。缺点:对CPU最不友好,在过期键比较多的时候,删除过期键会占用一部分CPU时间,对服务器的响应时间和吞吐量造成影响。周期性的随机检查一批设置了过期时间的key并进行处理,检查到的已过期的key将被删除。优点:可以通过限制删除操作执行的时长和频率来减少删除操作对CPU的影响。

2024-05-12 14:39:07 491

原创 Redis为什么快?

一个CPU同时只能执行一个线程的任务,如果是多线程的场景的话,不同线程去争夺CPU资源,上下文切换开销很大,所以redis采用了单线程。(注:Redis 6.0之前,服务端和客户端的连接以及如何去处理客户端的命令都是共用一个线程的,也就是单线程 , 在Redis 6.0之后,处理服务端和客户端的连接专门用多线程去跑了,但是处理命令还是单线程。但不是每个连接时时刻刻都有数据的,维护太多的线程会浪费资源,通过IO多路复用可以让一个线程监控多个socket连接。(1)Redis是基于。

2024-05-12 14:00:41 636 2

原创 Redis缓存策略

(读的时候不动缓存,那什么时候动缓存呢,那就是写的时候,对吧)。就相当于把redis当数据库来用了,要保证写的数据同步到redis中去,这种全量写,一般是不会读数据库的,数据库的压力就会很小,只扛写的压力。和Cache-Aside差不多,也是先从缓存中获取数据,没有就查数据库,然后放入缓存,区别是,Cache-Aside在于应用服务不再和缓存直接交互,而是先访问数据服务,数据服务自己来根据情况查询缓存或数据库。先去缓存中看看有没有数据,有数据就返回,没有数据的话,就去查数据库,然后把数据放到缓存中。

2024-05-11 18:47:26 469

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除