自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 如何使用wireshark 解密TLS-SSL报文

现在网站都是https 或者 很多站点都支持 http2。这些站点为了保证数据的安全都通过TLS/SSL 加密过,用wireshark 并不能很好的去解析报文,我们就需要用wireshark去解密这些报文。我主要讲解下mac 在 chrome 怎么配置的,浏览器一定要支持HTTP2。

2025-01-15 18:52:44 1475

原创 详解mysql和消息队列数据一致性问题

在本文中,我将重点分析一家医美公司的团队在使用消息队列时的奇葩做法。这家公司的技术团队选择了 Kafka 作为主要的消息队列,但在某些情况下却出现了数据未能成功消费的问题。为了应对这个挑战,他们又引入了 RocketMQ,并通过其延迟机制来弥补之前的不足。然而,这样的做法是否合理?这背后又隐藏着哪些技术思考与团队协作的缺陷?接下来,我们将深入探讨这家公司的消息队列应用,以及其中的潜在问题与改进方案。

2024-09-28 09:15:25 1245 1

原创 数据复制二(多主复制详解)

解决冲突最合适的方式可能还是依靠应用层,所以大多数多主节点复制模型都有工具来让用户编写应用代码来解决冲突。可以在写入时或在读取时执行这些代码逻辑:在写入时执行只要数据库系统在复制变更日志时检测到冲突,就会调用应用层的冲突处理程序。例如,Bucardo 支持编写一段Perl 代码。这个处理程序通常不能在线提示用户,而只能在后台运行,这样速度更快。在读取时执行当检测到冲突时,所有冲突写入值都会暂时保存下来。下一次读取数据时,会将数据的多个版本读返回给应用层。

2024-08-21 09:21:28 728

原创 数据复制一(主从复制详解)

数据复制就是相同的数据在多台机器上传输,多台机器可以在一个机房也不可以跨区域。通过数据复制有以下好处:降低访问延迟(数据复制到离用户更近的地方)、当机器出现故障时,可以切换到副本机器,从而提高可用性、多台机器可以同时提供服务,从而提高吞吐量。现在计算机技术来说数据复制就几种方法:主从复制、多主复制和无主节点复制。

2024-08-20 14:04:16 1183

原创 go 反射浅谈

golang 的反射里面,一个实例有两部分:reflect.Type 和 reflect.Value。reflect.Type 是不可以修改的,reflect.Value可以修改的。reflect.Type 可以通过 reflect.Value 得到,但是反过来则不行。我们先看几个例子,分别讲解一下。具体的可以执行看下。

2024-08-17 23:21:03 1108

原创 从0到1实现grpc 拦截器

拦截器简单来说就是我们可以在执行业务代码前执行一段代码,和gin 的中间件的概率是一样的。我们常常在拦截器会实现限流,熔断器,auth 认证等功能。首先我们自己可以实现一个拦截器。​fmt.Println("业务")h(ctx)h(ctx)下面是运行的结果1业务2业务这个肯定不对呀,inter1和 inter2 是两个拦截器 h 是业务代码,业务代码应该只执行一次呀。grpc 是怎么实现的呢。

2024-07-25 17:15:28 442

原创 堆算法详解

二叉堆是优先队列一种简单、常见的实现,但不是最优实现 理论上二叉堆可以支持O(logN) 删除任意元素,只需要 定位该元素在堆中的节点p(可以通过数值与索引之间建立映射得倒) 与堆尾交换,删除堆尾。把堆顶(heap[1)和 堆尾 (heap[n]) 交换,删除堆尾部 (删除最后一个元素) 然后从根向下进行一个调整(heapify Down) 每次与左右子节点中较大的一个比较,检查堆性质,不满足则交换,注意判定子节点是否存在 那么时间复杂度是O(logN)p+2,那么p节点的父节点为(p-1/2)(下取整)

2024-06-02 09:58:36 814

原创 递归-常规问题详解

递归在计算机算法中有很重要的地位,它可以解决条件具有重复性的问题。我们在快速排序和归并排序,都是利用了递归去解决问题的。写好一个递归代码不是太容易,很容易造成死循环最终内存泄漏。那么怎么写好递归代码呢,我总结了三点。递归的三个关键:定义需要递归的问题(重叠子问题)也就是说条件具有重复性。递归边界保护和还原现场还是拿快排来说:快排的子问题就是分别对基准数据的左右子数据列分别排序,这个问题具有重复性,递归边界就是left>=right。

2024-05-15 18:42:33 370

原创 算法-排序详解

计算机的工作之一就是对数据的处理,处理数据有一个常见的操作就是对数据排序,比如新闻系统总是按时间把最新的新闻推荐给我们,比如说以前我们讲到的二分查找,他也是基于数据的有序性。在这里我将详细讲解排序算法,下面是对排序算法的总结。

2024-05-12 22:03:58 1124

原创 微服务拆分

我们在软件开发的时候一直在谈论架构,那么什么是架构呢?计算机系统的软件架构是构建这个系统所需要的一组结构,包括软件元素、它们之间的关系以及两者的属性,简单来说就是元素和元素之间的关系。它的目标是可扩展性、可靠性、安全性、可维护性、可测试性以及可部署性并且可以快速的交付,为了实现上述目标,分解就特别的重要。接下来将详细阐述微服务的拆分。说到软件架构不得不提到软件架构的4+1视图模型:每个视图有以下的目的:逻辑视图:开发人员创建的软件元素。在面向对象的语言中,这些元素是类和包。

2024-05-08 17:35:39 1337 2

原创 二分查找详解

二分查找是一个非常重要的算法,特别当数据规模很大而且数据具有递增规律时,可以提高查询的效率,它的时间复杂度是log(N)。但是写一个没有问题的二分查找是十分不容易的,要考虑到正数的溢出,数据的边界问题。今天我要谈谈二分查找的几个变种,比如说一些数据具有一定规律的递增或者递减,二分答案,一个数据的前驱和后继等等,但是这些数据都是有一定规律的递增或者递减。

2024-05-06 23:34:05 874

原创 golang 归并回源策略

下面是我根据业务需求画了一个架构图,没有特别之处,很普通,都是我们常见的中间件,都是一些幂等性GET 请求。有一个地方很有意思,从service 分别有10000 qps 请求到Redis,并且它们的key 是一样的。这样一个简单的业务,Redis 就需要承担20000qps,此时监控 redis 我们会发现有一个峰值,如果Redis 没有值,这些流量会穿透到PostgreSQL,监控PostgreSQL也有一个峰值。

2024-04-04 16:53:04 1117

原创 设计模式一详解

当一个对象状态发生改变时,依赖它的对象全部会收到通知,并自动更新场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是藕合的,侵入式的,增加新的逻辑需要修改事件主体的代码观察者模式实现了低耦合,非侵入式的通知与更新机制上面的interface{} 为每个实例提供了统一的方法,那么抽象方法提供了添加实例以及统一遍历实例的方法。适配器模式,可以将截然不同的函数接口封装成统一的API实际应用举例,PHP 的数据库

2024-03-28 17:22:25 589

原创 mysql 排序底层原理解析

本章详细讲下排序,排序在我们业务开发非常常见,有对时间进行排序,又对城市进行排序的。不合适的排序,将对系统是灾难性的,这个不是危言耸听。可能有些人会想,对于排序mysql 是怎么实现的,它的底层原理是怎么样的,如果我加上分页,排序是不是就会快一些。关于这些问题,本章详细讲解。有人经常问我,mysql 优化的规则,总是不假思索的说ESR,E 是 equal ,S是sort。可见排序有多么重要,为了讲解方便,我先画个思维导图。上图标的1,2 是mysql 配置文件可以配置的。

2024-03-15 00:34:34 1704

原创 浅析 mysql 两阶段提交

在业务上,对数据的更新是非常频繁的,mysql 来说就是一条update 语句。大家有没有感觉update 语句对普通索引的更新总是很快,这是为啥呢?是不是很好奇更新语句的执行流程是怎么样的呢?由于语句执行错误,数据被污染,我们会让DBA 帮我们恢复到更新前的状态,这又是怎么完成的呢?对于这些问题,会在接下来的文章详细讲解,本章引擎是innodb 引擎。为了方便讲解,我将画一个流程图,这个流程图包括各层需要的日志文件。

2024-03-13 19:39:17 1467

原创 mysql 获取行数的n种方式详解

在开发中,经常很多用在统计表的总数据时,有用count(*),count(1) 还有count(字段)。这篇文章我将详细讲解他们之间有什么不同,他们的底层是怎么实现的。你会发现一个现象随着记录越来越多,select count(*) from t_user ,这条语句执行也会越来越慢。你惊奇的发现,就这条语句而已myisam 比 innodb 要快,为什么呢,就拿innodb 而言,这条语句第一次查询比第二次查询要慢很多,又是为什么呢?下面关于这些问题我都会给大家详细解决。

2024-03-12 14:11:06 2886

原创 算法-位运算

机器是采用二进制对数值进行表示、存储和运输,在程序中恰当使用二进制,可以提高运行效率。本篇文章我们讲下位运算相关的问题。

2024-03-11 19:57:17 586

原创 redis 缓冲区详解(性能优化缓冲区优化)

在我的《Redis 为啥那么快》这篇文章中,详细总结了Redis 为啥那么快。今天当我要详细阐述Redis 的缓冲区时,意识到应该加上Redis 的缓冲区。我们假设没有Redis 的缓冲区,客户端向服务端发送数据,必须等待Redis 的服务端去处理,大家都知道Redis 是单线程的,虽然这么说不是很准确,为了描述,也只好这么说了。如果没有及时处理,那客户端不就阻塞了吗,有多个客户端,redis 阻塞的时间不是更长了吗?

2024-03-11 13:49:37 1893

原创 mysql 优化——磁盘空间优化

有的时候,表的数据太多,为了提高查询以及存储,就把历史数据放到一个历史表里,在把历史数据删除,发现虽然历史数据删除,表的大小并没有发生改变。Innodb 表有两部分,即:表结构定义和数据。在 MySQL 8.0 版本以前,表结构是存在以.frm 为后缀的文件里。而 MySQL 8.0 版本,则已经允许把表结构定义放在系统数据表中了。因为表结构定义占用的空间很小,所以我们今天主要讨论的是表数据。

2024-03-10 17:36:40 1325

原创 mysql 性能优化——磁盘刷脏页性能优化

大家是不是感觉mysql 更新挺快的呀,有没有想过mysql 更新为什么那么快。按道理说,mysql 更新都是先找到这一行数据,然后在去更新。意味着,就有两次磁盘操作,一个是磁盘读,一个是磁盘写。如果真的是这样的话,肯定会很慢呀,mysql 也没有那么傻。当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log 里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面。

2024-03-10 11:16:27 1419

原创 Redis 内存的优化

我想讲一下怎么提高Redis 内存的利用率,redis 的数据是保存在内存中。对内存的利用率低,意味着存的数据很少,并不意味着就没有内存了,而是这些内存没法利用了,后果就是会自动删除一些key,删除key 大量的内存释放,同时会把释放的内存放到一个空的链表里,如果操作系统开始了swap,会把数据保存在磁盘。这些都会影响redis 性能。上面讲了内存利用率低会造成什么连锁的反应,内存利用率低就是内存碎片,接下来,我将详细讲述什么是内存碎片,对于Redis 我们该怎么解决内存利用率低的问题。

2024-03-09 16:06:54 941

原创 字符串索引的优化

字符串加索引无非就是两种方式,一是给整个字符串加索引,二是给部分字符加索引也就是前缀索引。这两种方式各有优点吧,他们的区别是什么?究竟怎么加索引,要不要加索引,怎么加索引,要根据具体的业务而定。这篇文章讲详细阐述这几个问题。字符串索引和主键索引有很大区别,作为主键索引,我们一般会保证主键递增,也就不会有页的分裂。而字符串索引由于业务的原因,没法保证数据的顺序性,就会有页的分裂来保证索引的顺序性,还好非聚簇索引,叶子节点没有整行的数据。

2024-03-09 11:34:14 866

原创 redis 性能优化三

如果Redis 没有执行大量的慢查询,同时也没有删除大量的过期的keys,那么我们该怎么办呢?那么我们是不是就应该关注影响性能的其他机制了,也就是文件系统和操作系统了。Redis 会把数据持久化到磁盘,这个过程依赖文件系统来完成,文件系统把数据写回磁盘的机制,会直接影响到Redis 持久化效率。而且,在持久化的过程中,Redis 也还在接收其他请求,持久化的效率高低又会影响到Redis 处理请求的性能。

2024-03-07 18:54:00 1035

原创 redis 性能优化二

性能优化的第二篇文章,将重点讲一下Redis 的响应延迟,响应延迟如何对redis 进行优化。这个延迟不是说一个命令或者几个命令变慢了,延迟了几秒,就说Redis 变慢了。在不同的软硬件环境下,Redis 本身的绝对性能并不相同。要根据Redis 的基线性能做判断。所谓的基线性能呢,也就是一个系统在低压力、无干扰下的基本性能,这个性能只由当前的软硬件配置决定。怎么确定基线性能呢?

2024-03-07 12:03:52 1327

原创 redis 性能优化一

说到redis 性能优化,优化的目的是什么?提高响应,减少延迟。就要关注两点,一是尾延迟,二是Redis 的基线性能。只有指标,我们的优化,才有意义,才能做监控以及报警。这些指标需要借助一定工具进行压力测试,高于这个值就说明需要优化了,这些值,不是绝对的,不同的服务器配置,都会有一些变化,下面我将介绍这两点。

2024-03-06 23:16:44 1056

原创 redis 为啥那么快

我们一直说redis 是单线程的,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。其他的功能,比如持久化、异步删除、集群数据同步,是由子线程完成的。所以说redis 是单线程,是主路径上的操作是单线程,并不代表只有一个线程。这一点大家要注意,接下来,我会详细给大家讲解redis 为啥是单线程以及它为啥那么快。

2024-03-05 21:11:16 860

原创 幂等性设计

幂等性设计,就是说,一次和多次请求某一个资源应该具有同样的副作用。为什么我们要有幂等性操作?说白了,就两点:1、网络的不稳定性 2、服务状态不确定性,服务状态不仅有成功,失败,还有超时。超时又有多种原因引起的,有可能是网络抖动,也有可能是负载引起的。对于这种情况,需要做重试,重试的后果是服务被调用了多次,数据不对,业务当然出问题了。打个比方吧,我们网上购物,去支付时,网络原因超时,我们做重试,在我们发起重试后,网络好了,是不是有可能执行了两次,扣了两次钱。这样的情况其实有很多很多,还比如,订单服务重试,创建

2024-03-03 23:06:07 994

原创 redis 为什么会阻塞

大家对redis 比较熟悉吧,只要做项目都会用到redis,提高系统的吞吐。小米商城抢购高峰18k的qps,redis 在其中扮演着非常重要的角色。有时我们操作不当,redis 阻塞了,影响了整个业务。我记得2018年的时候,顺丰就出现了一个事故,有同学在线上对redis的一个操作,直接阻塞了,影响公司的整个业务,后面这位同学被辞退了。如果它对redis比较了解的话,也不会出现这样的事故。redis 为什么会阻塞,与它的本身设计有一定关系。

2024-03-02 16:01:47 1406

原创 普通索引和唯一索引详解

面试的时候有时会问面试者,普通索引和唯一索引有什么区别。很多人,甚至工作很多年的工程师回答的千篇一律 “普通索引可以有重复的值,唯一索引不能有重复的值”。于是我又问,这两个索引这两个索引效率哪个高,很少有人回答的很好。下面我会从查询和更新多个维度去剖析这两个索引的区别。现在我们系统有这样一个需求,根据用户的身份证查询用户的信息,用户表的数据很多。

2024-02-29 16:33:22 737 1

原创 浅谈mysql mvcc

mvcc 与一个事物的隔离级别有关,未提交读永远读的是当前值,串行化是通过加锁实现,这两种隔离级别都与mvcc 没有任何关系。只要一提到mvcc应该想到的是读提交以及可重复读,大家有没有想过都是mvcc,为啥这两个隔离级别所呈现的结果有些不一样呢?难道会有两套mvcc 吗?当然不是,对于这个问题,稍后我会说明的。我先举一个简单的例子。下面是一个表的初始化语句。

2024-02-29 01:06:04 1042

原创 golang 泛型详解

Go 在1.18 中添加了泛型,这样Go 就可以在定义时不定义类型,而是在使用时进行类型的定义,并且还可以在编译期间对参数类型进行校验。Go 目前只支持泛型方法,还不支持泛型接口,下面我会详细介绍Go的泛型使用以及常见的使用错误。其他概念性的东西我不想说太多,大家可以自己百度。

2024-02-28 13:17:19 2330

原创 Redis String 类型底层揭秘

Redis 的 string 是个 “万金油” ,这么评价它不为过. 它可以保存int,float 甚至二进制也可以保存。对于key,value 这样的单值,查询以及插入都是O(1)时间复杂度。满脑子都是它的优点,真的就那么好吗?如果不了解它的底层结构,会有很多坑的,下面让我们细细说来。有这样一个需求,我们要开发一个图片存储系统,要求这个系统能快速地记录图片ID和图片在存储系统中保存的ID(图片存储对象ID)。同时还更够根据图片ID快速查询图片存储对象ID。

2024-02-27 15:57:55 1463

原创 golang 装饰器模式详解

我一直以来对golang的装饰器模式情有独衷,不是因为它酷,而是它带给我了太多的好处。首先我不想说太多的概念,熟记这些概念对我的编程来说一点用处没有。我只知道它给我带来了好处,下面谈谈我的理解。这种模式可以很轻松地把一些函数装配到另外一些函数上,让你的代码更加简单,也可以让一些“小功能型”的代码复用性更高,让代码中的函数可以像乐高玩具那样自由地拼装。重要的是你不用修改代码以前的功能,对以前的功能没有影响,而是动态的,很方便的扩展函数的功能。下面我将举几个例子说明下。

2024-02-26 17:14:11 1008 2

原创 mysql 事务详解一

提到事务,大家肯定不陌生。在我们现实生活中也是存在的,比如我们去超市购物,然后去支付。虽然是两个步骤,必须保证同时成功,这个交易才可以完成。如果这个场景,拿到我们购物系统,就是几张表订单表、支付表、流水表。你往订单表插入一条数据,同时也会往支付表,流水表拆入一条数据,这个插入操作必须同时成功。这就是事务,简单来说事务就是要保证一组数据库操作,要么全部成功,要么全部失败。在mysql 中,事务支持是在引擎层实现的。

2024-02-23 16:57:31 1133

原创 redis GEO 类型原理及命令详解

我们有一个需求是用户搜索附近的店铺,就是所谓的位置信息服务(Location-Based Service,LBS)的应用。这样的相关服务我们每天都在接触,用滴滴打车,中午去美团订外卖等等。当我们用这些服务方便我们的生活的时候,大家有没有想过是怎么实现的。目前市场上很多软件比如Es,Redis 都提供了类似的功能,他们底层都是用的GeoHash 编码,只不过底层的数据结构不同。今天主要讲的是Redis 的 Geo 如何实现这个功能。

2024-02-22 14:43:59 4065

原创 mysql 锁详解

为什么要设计锁,锁设计初衷是为了解决多线程下并发问题。出现并发的时候用锁进行数据同步,避免因并发造成了数据错误(数据覆盖)。可见锁的重要性,并不是所有的数据库都有锁。比如Redis,单个操作是原子性的,并且是单线程的,并发请求会在队列排列,请求是按顺序执行的,就不需要锁。Mysql 需要锁,mysql 是多线程的,并发操作要保证数据的一致性,需要通过锁进行数据同步。根据锁的范围来讲,mysql 的锁分为全局锁、表级锁和行锁。

2024-02-21 20:32:27 1719 1

原创 详解 websocket

WebSocket该协议在规范RFC 6455中进行了描述,它提供了一种通过持久连接在浏览器和服务器之间交换数据的方法。数据可以作为“数据包”双向传递,而无需中断连接或发出额外的 HTTP 请求。为啥不用HTTP1.1 呢,HTTP1.1的双向通信只能通过轮询,会浪费很多网络资源,因为每次都需要tcp的三次握手以及四次挥手。而且HTTP1.1不能从server到client 进行消息推送,消息的实时性得不到保证。

2024-02-01 12:43:03 2938

原创 小米服务治理——客户端熔断器(Google SRE客户端熔断器)

当某个用户超过资源配额时,后端任务应该迅速拒绝该请求,返回一个“用户配额不足”类型的错误,该回复应该比真正处理该请求所消耗的资源少得多。然而,这种逻辑其实不适用于所有请求。例如,拒绝一个执行简单内存查询的请求可能跟实际执行该请求消耗内存差不多(因为这里主要的消耗是在应用层协议解析中,结果的产生部分很简单)。就算在某些情况下,拒绝请求可以节省大量资源,发送这些拒绝回复仍然会消耗一定数量的资源。如果拒绝回复的数量也很多,这些资源消耗可能也十分可观。

2024-01-31 10:22:17 2231 2

原创 进程和线程和协程区别

当发生线程上下文切换时,需要从操作系统用户态转移到内核态,记录上一个线程的重要寄存器值、进程状态等信息,这些信息存储在操作系统线程控制块中。上下文切换速度:协程切换不用经过系统用户态和内核态切换,协程切换只需要保留极少的状态和寄存器变量值(SP/BP/PC),而线程切换会保留额外的寄存器变量值(例如浮点寄存器),线程切换的速度大约是1~2微秒,协程切换的速度为0.2微秒。大多情况下,线程是进程的组成部分,一个进程中可以存在多个线程,这些线程并发执行并共享进程的内存等资源。

2023-12-20 07:50:55 336

原创 限流算法,基于go的gRPC 实现的

提供各种限流算法分别是分布式限流以及集群限流,以及他们原理优缺点,和具体实现

2023-12-06 05:08:58 1398

空空如也

空空如也

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

TA关注的人

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