自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 RocketMQ是参考kafka进行实现的为什么rocketMQ与kafka性能差距很大呢?

我没有在文档与书籍中看到为什么 rocketMQ 要使用混合储存的方式,但是我在探究他们的不同的时候发现 kafka 存在分区数量庞大(10000+)会导致性能下降的问题.调整中心节点: rocketMQ 使用的无状态的 nameserv 的模式,只储存他们的端口消息,不储存元数据,在大 topic 的情况下对中心节点的影响很小。采用混合储存的方式减少文件的数量(文件数量减少 1/3)

2025-04-06 21:29:11 652

原创 消息队列(kafka 与 rocketMQ)

我没有在文档与书籍中看到为什么 rocketMQ 要使用混合储存的方式,但是我在探究他们的不同的时候发现 kafka 存在分区数量庞大(10000+)会导致性能下降的问题.调整中心节点: rocketMQ 使用的无状态的 nameserv 的模式,只储存他们的端口消息,不储存元数据,在大 topic 的情况下对中心节点的影响很小。磁盘数据->内核空间->用户空间->socket 发送缓冲区->网卡。RocketMQ: 发送:12MB/s;sendfile: 只关心发送了几个字节,不关心发送的内容。

2025-04-06 21:19:27 657

原创 消息队列的选择与配置

rocketMQ 的 message 是混合储存的,也就是所有消息都是混合储存在一个 file 中,那么读取就是一个文件的 IO 效率,在多线程消费其实并不能增加他的 IO 效率。RocketMQ 的官方文档: https://rocketmq.apache.org/zh/docs/kafka 官方文档: https://kafka1x.apachecn.org/b. 去重: 每条消息会有唯一序列号,对于重复消息进行去重(服务器内部做的)接收400MB/s(最高情况)● 消费者的"仅一次"语义的实现"

2025-03-31 21:36:07 515

原创 kafka 与 RocketMQ对比

消费-线程数(15 分区)

2025-03-30 21:23:20 1205 1

原创 golang 高性能的 MySQL 数据导出

数据库负载:大量数据查询会增加数据库的CPU、内存和I/O负担,可能影响其他操作。网络传输:大数据量传输会占用大量带宽,导致网络延迟或超时。服务器内存: 消耗太大,影响其他业务运行。

2025-03-11 21:36:02 482

原创 前后端鉴权的策略

二次验证: 验证 token 的颁发时间与密码更新时间(如果 token 颁发时间小于密码更新时间,则 token 无效)总结: 此方法太复杂,还不如直接使用 cookie-session/Opaque Token 模式进行验证方便。

2025-03-09 17:06:41 617

原创 jwt 存在的无状态的安全问题与解决方案

可以更好的解决安全问题,还可以进行安全警告(比如异地登录,异设备登录等等),告知客户有人正在非法访问他的账号.这样我们就解决了密码泄露/token泄露无法强制下线的安全问题。解决密码泄露/token泄露无法强制下线的安全问题。成本比方案1低了80%泄露的情况与解决方案。

2025-03-04 21:20:50 991

原创 redis 与 DB 的一致性 7 种策略

使用(Redis)缓存主要是利用 缓存( Redis)高性能的特性减少DB的重复查询就是数据需要多次查询,并且每次查询的结果是相同的,这时候加到缓存中,可以拦截大量的请求在缓存层,减少db的请求压力举个例子一些 IM 系统的总的 QPS 有几十万(qq,wx 这些)但是每个人接受的消息是不同的,并且消息是一次性消费的,所以针对单行消息而言,QPS 是小于 1 的并且是一次性消费,不涉及多次重复查询,即使总的 QPS 非常高,也不会使用缓存(IM 系统会使用Redis,但是不是做缓存使用的)

2025-03-03 19:57:24 1562

原创 redis 缓存击穿问题与解决方案

当我们使用redis做缓存的时候,查询流程一般是先查询redis,如果redis未命中,再查询MySQL,将MySQL查询的数据同步到redis(回源),最后返回数据流程图为什么使用 redis 作为缓存: 减少 DB 层次重复数据查询的压力redis 有 10 万QPSDB 只有几万(MySQL 1 万 QPS)热 key 失效,当一个访问量特别高的一行数据在 redis 中失效,所有的请求全部打到 DB 层,可能直接将 DB 打爆。

2025-02-11 17:05:23 1833

原创 具体场景的 MySQL 与 redis 数据一致性设计

产品的要求: 修改之后自己能马上看到最新的数据,10s内其他用户能看到最新的数据情况1: 修改的是一些爆火的视频,可能每秒有上万的访问量情况2: 修改的是爆冷的视频,每天只有一个访问量产品的要求: 更改完成后自己能马上看到最新数据,其他用户要在 10s 内看到新数据场景分析用户主页是读写请求量不算太高的场景,基本不会遇到热 key 问题为什么?:因为用户数据并不是我们的主要业务,只有主要业务(请求量最大的业务)才容易出现热key 问题。

2025-01-16 19:00:54 1878

原创 MySQL 与 Redis 的数据一致性问题

简单来讲,我们只能保证先到的请求的第一阶段写的执行顺序(MySQL 内部的事务),第二阶段写就无法保证执行顺序(除非使用强一致性方案),这时候如果使用更新 Redis 的方案就有数据错误的风险。这种清除 Redis 的策略如果有频繁的更新对导致缓存层(Redis) 会失效, 大量的请求会打到 mysql 上面,mysql 可能直接被打爆,造成严重的事故.这时候Redis 的数据是错误的,会导致后面查询的时候全部查询到错误的数据(只能重新加载 MySQL 数据到 Redis 才能恢复)

2025-01-13 21:18:20 2906 1

原创 单体 vs 微服务 怎么选?

随着产品方向的确定,功能也会越来越复杂,一般 10-50 万行代码的样子就要开始考虑服务的拆分了(具体情况还要看项目的具体业务但还是从团队规模,开发周期,错误量等方面综合考虑)说简单一点,单体开发不下去了,改一个地方,要同时对很多地方进行调整,更加容易出 bug,一出 bug 整个服务全部受到影响;成本低,开发快,功能上线容易,能够快速上线并收获用户的反馈(先花小的代价摸清产品未来的发展方向)2. 依赖项越少,出问题影响的范围小(依赖的东西可能出问题,尽量减少没必要的依赖数据库什么的)

2025-01-11 14:03:56 1661 1

原创 分布式锁 Redis vs etcd

当我们不需要很强的一致性,但是需要比较高的性能的时候,大量并发获取锁的情景下我们可以选择 Redis 的分布式锁如果我们需要强一致,高性能,高并发的场景的话我们可以使用 Redis 的 redlock 模式如果我们需要强一致,但是性能不需要太高,并且并发数量并不高的情况,可以选择使用 etcd 的分布式锁。

2025-01-09 15:48:47 2452

原创 MySQL 锁那些事

有的人说读提交不会显示加锁,我觉得不加锁不科学,不加锁百分百会出现读写并发冲突问题,一定会报错;行锁只有索引的条件下才会生效,没有索引会锁全表,造成其他线程阻塞,连接大量堆积,严重影响性能.索引不仅会减少磁盘 io 的次数加快数据的查询,还可以提高并发情况下的读写性能表现.但是 MySQL 不会做一个有问题的东西给大家用,那为什么。没有索引的查询与更新数据在并发情况下表现更差.行锁是通过索引实现的,主要分为两个阶段。

2025-01-02 15:43:42 1663

原创 MySQL 索引

加快查询的一种数据结构,包含:索引字段数据(一般情况:主键索引就是原本的数据,二级索引就是储存主键)你可以理解就像一本书的目录一样;根据索引字段定位到数据的位置,从而快速拿到数据减少回表减少 io 次数的手段当我们查询的字段包含在索引中时,我们就不需要回表而直接返回数据索引中有哪些字段?索引字段主键当你查询走了索引,并且返回的值刚好是索引字段或者返回字段的时候就可以避免回表而直接返回数据简单点来讲,就是我已经拿到我需要的东西了我干嘛还要回去呢?还是上面的例子(语文,数学,英语)的索引。

2025-01-01 21:14:01 1932

原创 MySQL 的事务与多版本并发控制(MVCC)的那些事

ACID数据持久化磁盘的消耗比较大(慢),MySQL 储存数据的流程是先存缓冲区(内存),再找合适的时机落盘,这样性能会高非常多(内存的 io 有百万,千万级 qps)但是如果数据没来得及落盘,服务就崩溃了(断电),那么数据就有丢失的风险redo log(重做日志): 解决崩溃恢复的数据丢失问题redo log会记录写(命令)数据的偏移量(数据做了什么修改)redo log会通过追加的形式将日志记录到磁盘redo log 的落盘机制(可以设置的)事务提交立即落盘。

2025-01-01 14:48:59 1410

原创 分库分表那些事

ⅱ. 重试机制: 确保每个任务都能够收到,没收到就会重试。所以分片键的选择很重要,要尽量让查询不要分散到所有库中。例子: 现在分成了"用户库",商品库,订单库三个库。如果你的数据在不同的数据库,如何保证数据一致性.ⅰ. 确认机制: 确保每个任务都执行成功。c. 消息队列 MQ如何实现最终一致性。产生原因:消息队列的重试机制。ⅲ. 让你设计如何做?如何保证他们的一致?

2024-12-31 21:08:51 667

原创 MySQL 的分库分表

一个订单系统,订单信息和用户信息被拆分到不同的库。如果需要在一个事务中同时更新订单状态和用户余额,就涉及跨库事务。分库后,复杂查询(如多表 JOIN 或聚合操作)变得困难。用户按 ID 分片,但某些大客户的操作频繁集中到一个库,造成热点。查询某用户的所有订单和支付记录,但订单和支付信息在不同库中。缺点:UUID 长度大,索引性能较差。优点:高效,生成的 ID 有序;缺点:依赖外部服务。设置每个库的自增 ID 起始值和步长。分库后,数据可能分布在不同的库中。库1:1, 3, 5…库2:2, 4, 6…

2024-12-29 21:40:26 1548

原创 MySQL 性能瓶颈,为什么 MySQL 表的数据量不能太大?

不是 B+树导致的磁盘 io 变多(b+树影响小,平均查询时间只会多几毫秒,MySQL 又是多线程的,并阻塞其他线程的查询任务);一个全表扫描的查询: 1000 万数据的全表扫描 2.1s。● 网络IO: 20 万 qps(tcp)上面已经分析了 MySQL 的性能瓶颈。● 磁盘IO: (2 万 qps)–● 内存 IO : 千万级 qps。

2024-12-27 20:23:52 2284 1

原创 MySQL 构建 1000 万数据太慢?如何快速构建大量模拟数据?

我的方案就是:**一条 insert 命令插入 多条数据(1万 条甚至 10万条)**避免频繁的执行 insert。平均 2-3 秒钟插入 10 万条数据,1000 万数据 4 分钟就好了,性能高了 25 倍.网上创建模拟数据的方式大部分都是建立一个循环,一行行插入,但是这样的效率不高确实。逻辑就是使用一个循环1000万次的for创建对象并调用 create 方法。但是发现一个巨大的问题,创建速度巨慢,几乎1分钟10万条。于是我使用gorm的Create方法进行创建。于是我打算使用一种高性能的创建方案。

2024-12-27 15:53:29 281

原创 MySQL 查询大偏移量(LIMIT)问题分析

是跳过 id 的前面的10000000 条数据从 10000001条开始,需要扫描到 10000001 条。1. 走 age 的索引,取出根据 age 排序的第 10000001 到 10000010 条数据的主键。操作本身是没太大消耗的,就是查询数据的时候只取多少条数据(这里是取 10 条),主要是前面的。: 是直接定位到 id=10000000 的数据取大于它的数据。所以 OFFSET 越大,需要扫码的数据行数越多,消耗越大.条件字段 age,排序字段主键id(默认)OFFSET是跳过多少行数据,

2024-12-26 19:21:17 555

原创 OSI 网络 7 层模型

物理,链路,网络,传输,会话,表示,应用问题: 他们都有什么用,解决了什么问题?

2024-12-25 19:34:32 794

原创 cookie,session,token 的区别

有效期 1 天),然后讲存条进行加密变成了一个加密存条(************),然后给张三,然后告诉张三,拿着这个可以到任何一家银行取到钱。第二天张三去银行的二号分行里取钱,就把加密存条(************)给银行,银行先通过密码本进行解密,发现内容是(姓名:张三;有效期 1 天),就给张三 1 元。第二天张三去银行里取钱,就把小票(001)给银行,银行根据小票查询账本找到张三的存款记录,给张三 1 元。第二天张三去银行里取1块钱,就把存条给银行,银行核验存条,就给张三 1 元。

2024-12-25 12:39:08 561

原创 tcp 的重传,流量控制,拥塞控制

假设发送了 1,2,3,4,5,6,7 都 包, 前面 6 个包都没有收到,但是后面有一个 ack 7 证明包 1~6 都已经收到了,只是前面的 ack 丢包了. 就不需要重传了。传后面所有的包:假设发送了 1,2,3,4,5,6,7 包, 1 包接受到了,只有2没有收到,那么 3,4,5,6,7 包就重复传输了,增加了网络的压力。传一个包: 假设发送了 1,2,3,4,5,6,7 包, 1 包接受到了,2,3,4 都没有收到,那么一个个重传就需要重传 3 次,效率太低。

2024-12-24 19:58:28 1131 3

原创 tcp 的三次握手与四次挥手

问题: B 不知道 A 是否能收到发出的 FIN 信号,如果丢包,A 会保持 tcp 连接。问题 3: (假设服务端收到请求,并同意连接)服务端不知道客户端是否可以接收到数据.问题 2: A不知道 B 的数据是否已经传输完成,可能会丢失数据。问题 1: A不知道 B 的数据是否已经传输完成,可能会丢失数据。问题 1:A不知道 B 是否能收到断开连接的信号。问题 1: 服务端不知道客户端是否可以收到数据。客户端(请求连接:SYN)->服务端。客户端(请求连接:SYN)->服务端。

2024-12-24 13:21:07 556

原创 MySQL 的锁

作用: 协调行锁与表锁的关系,用于快速判断一个表是否上行锁锁,意向锁会与表级排他锁冲突.缺点: 在写操作比较多的情况下会出现大量的冲突回滚性能不佳.场景:上行锁时候会使用,上表锁的时候先判断是否有意向锁冲突。作用: 某个范围条件的锁,一般用于避免数据幻读。排他锁会与排他锁,共享锁都冲突(不可同时读写)场景: 定义了自增 id,在写入数据的时候。场景: 操作某个范围的(包含某个值)数据。场景: 在要对表的结构进行修改的时候会加。场景: 操作某个范围的数据。作用: 自增 id 的锁。作用: 单行数据的锁。

2024-12-18 20:31:19 369

原创 MySQL 事务

然后A给B转账1000元,A的余额减1000元,B的余额加1000元,这时 A的余额1000元,B的余额1500元,总计还是2500元,事物前后的数据是一致的。如果制定的规则是 扣除金额是增加金额的两倍,那么总金额一定会丢失扣除金额的一半,因为MySQL 是按照管理员制定的规则进行运行保持数据的一致.而不是根据他的值,最后值的变化一定是满足管理员的规则的.这便是数据的一致性。事务的Read View 不会改变,可见的数据不会改变,每次可以获取到的数据都是事务开始之前的状态。

2024-12-17 19:45:16 915

原创 mysql 的 bin log 与 redo log 的区别

mysql 对于写操作不会立即落盘,而是先储存到缓冲区,在选合适的时机落盘为什么不使用 binlog 做崩溃的恢复,主要是因为 binlog 无法判断哪些数据已经落盘,哪些数据还没有落盘,这样要恢复只能全部重新加载,消耗太大.redo主要应对的就是服务崩溃的快速恢复,所以只需要保存近期的数据就可以了,所以 redolog 文件的大小是有限的.

2024-12-17 14:48:45 343

原创 mysql 的undo log与redo log

好处: mysql 的写的性能会高非常多;就是磁盘顺序写入的性能是 60 多万的 qps,mysql 还不是顺序写,性能会更低, 但是内存写的性能在上千万qps,性能相差几十倍.他每个数据的大小是固定的,这样就不会涉及到数据的重写问题,会快非常多,但是还是没有顺序写快。mysql 的事务没有提交,就会回到事务开始前的状态,但是 redo log只能恢复到故障/断电之前,并不能恢复到事务之前的状态.不是的,mysql 新增的数据都是先储存到缓冲区,再找合适的时机将缓冲区的数据一起落盘。

2024-12-16 15:59:08 801

原创 mysql 的 binlog 原理

SBR(语句级): 是记录执行的 SQL 语句,适用于简单且没有复杂操作的场景。RBR(行级): 是记录数据变动的每一行,适用于确保数据一致性要求更高的场景。MBR(混合模式): 是 默认使用 SBR,只有在遇到非确定性操作(如 NOW()、RAND())或者可能导致主从不一致的操作时才会使用 RBR。

2024-12-12 20:26:05 890

原创 时间轮算法 2

将时间分成一个个时间格,每个时间格上面存放改时间刻度要执行的方法,每个方法都加到对应的时间格上面(比如 1s 一个时间格,一共 60 个时间格,你添加一个 20s 后的延时任务,那么任务将会挂到当前时间格位置再往后的 20 个时间格上面,时间调度器会让时间格下标每一秒向后移动一位,并扫描执行挂在那个时间格上面的方法)使用多层时间轮的结构,上层时间轮 的时间格存放指向下层时间格的指针,那么上层时间格的时间跨度就是下层时间轮的时间跨度的总和,运行的逻辑就是下层转一圈,上层转一格.

2024-12-12 16:05:03 565

原创 mac 激活 typora

找到/Applications/Typora.app/Contents/Resources/TypeMark/ page-dist/static/js/Licenxxxxx.js 文件。

2024-12-11 19:50:43 301 1

原创 golang实现简单的redis服务4.0(持久化)

如果在生成RDB是主线程收到了写操作,这些数据会在新的临时空间储存,等持久化完成才回到原本的空间,查询的话先走临时的空间(最新的数据),再走原本空间.保证查询的是最新的数据.bgsave:主线程会fork一个子线程去进行持久化操作,生成新的RDB文件,然后替换旧的文件,通知主线程并退出。save:会阻塞服务器直到持久化完成,期间不接受其他的请求.可能会造成大量的请求积压,影响redis的性能。那么我们只需要保留最新的结果,而中间的结果可以去除掉,这样可以减少aof文件的大小。

2024-12-10 20:26:35 720

原创 时间轮算法

一个比较形象的比喻就是闹钟,当你想要再某个做某件事情,你就会去定一个闹钟,闹钟到点后就会提醒你该做的事情时间轮就像一个闹钟,再某个时间执行某个方法但是时间少无穷无尽的,所以如果使用一条时间线去添加任务那么空间复杂度将是无限大。

2024-12-10 17:48:50 212

原创 golang实现简单的redis服务4(实现过期时间功能)

原理: 使用一个队列进行维护,如果一个key被使用那么就将这个key放在对头,如果队列满了(空间满了)再加入数据就会从队尾淘汰一个数据,再将新数据加到对头。根据实际需求选择合适的内存淘汰机制,一般会使用volatile进行淘汰,因为没设置过期时间一般默认为需要长期缓存的数据.这是一个折中的方案,既不会向立即清除那样消耗太多的cpu,又不会让不使用的数据长期停留在数据库中。原理: 统计每一个key的使用次数,需要淘汰的时候,淘汰使用次数最少的key.定时清除: 定时扫描过期字典,将过期的数据清除。

2024-12-10 15:54:54 1030

原创 golang 实现简单redis服务3(实现多类型数据结构支持)

mysql是磁盘数据库,他的性能瓶颈并不是数据操作的速度,而是磁盘io,他需要的是更少的磁盘io才能有更高的性能,跳跃表与红黑树类似,当数据太多的时候,跳跃表的层数会更多,需要磁盘io的次数也会更多,速度反而会更慢;而使用B+树的格式,树层数会很少,磁盘io会很少,性能会更高.有序集合在集合的基础上面增加了排序的特性,每一个成员都有自己的分数,通过分数进行排序的,底层使用的跳跃表的数据形式,上层的节点有指向下层节点对应位置的指针,思路就是利用二分查找的方式提高查询效率,有点像红黑树.

2024-12-09 21:17:54 401

原创 golang实现简单的reids服务2

一般第一个是方法名set,get什么的,第二个是key值,第三个是val值(如果是get就没有第三个),后面是过期时间什么的.一个命令包含前面一个命令数据的长度,比如$3 表示后面的数据长度为3;然后在长度下一行才是数据;当然可以,需要实现redis的RESP通信协议。明白了工作原理我们就可以封装RESP协议支持了。RESP使用\r\n作为换行符。*2,*3表示命令的个数。

2024-12-08 21:32:09 312

原创 golang实现简单的redis服务

● 数据包: 长度(4byte)+方法(1byte)+数据json。○ 依次处理待处理队列的请求(chan)数据,处理并返回。■ 构建请求处理池: 不需要反复创建chan。● 数据处理: 单线程map读写。■ 队列大小: Max指定。● 协议: tcp通信。

2024-12-07 21:10:53 527

原创 go锁与chan的性能对比

在单线程下:锁 :128537480 qps;多线程下: 锁 : 15528596 qps;单论性能,锁要比chan更加优秀。

2024-12-07 15:06:11 564

原创 json与proto序列化,反序列化性能对比

相当于分发信封,一种是叫道名字的来取(json);一种是所有人通过信封的顺序排好了对,一个个拿就可以了(proto).而且proto只包含数据体,没有{与: ,标签,结构更紧凑,更小.json是通过标签将数据映射到对应的字段。proto是通过顺序直接填充值进去。有数据支撑比单独说快更具有说服力。

2024-12-05 20:00:36 245

空空如也

空空如也

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

TA关注的人

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