自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 GO语言自底向上优化

首先我们明白GO语言GC触发条件是由比例来触发的。例如,当前存活内存10GB,触发比例是100%,因此下次触发GC的时候是当内存达到20GB的时候触发GC。CFS算法在休眠进程在唤醒时会获得vruntime的补偿(减少vruntime,提高这个进程优先级),它在醒来的时候有能力抢占CPU是大概率事件,这也是CFS调度算法的本意,即。(值得注意的是,这部分多占用的物理内存依然是被除 Ballast 以外的对象所使用,不存在浪费问题,Ballast 本身仅仅存在于虚拟内存中,不会被实际地映射物理页面)

2023-08-16 22:59:57 516

原创 定位服务端出现大量 CLOSE_WAIT 状态

第 3 步没有做,有新连接到来时没有调用 accpet 获取该连接的 socket,导致当有大量的客户端主动断开了连接,而服务端没机会对这些 socket 调用 close 函数,从而导致服务端出现大量 CLOSE_WAIT 状态的连接。:第 2 步没有做,没有将服务端 socket 注册到 epoll,这样有新连接到来时,服务端没办法感知这个事件,也就无法获取到已连接的 socket,那服务端自然就没机会对 socket 调用 close 函数了。被动方,代码逻辑有问题,没close。

2023-08-10 22:24:38 491

原创 epoll的ET。 分别是边缘触发(edge-triggered,ET)和水平触发(level-triggered,LT)。

epoll 支持边缘触发和水平触发的方式,而 select/poll 只支持水平触发,一般而言,边缘触发的方式会比水平触发的效率高。

2023-08-10 22:14:17 396

原创 IO密集时epoll还高效吗?

连接密集(短连接特别多),使用epoll的话,每一次连接需要发生epoll_wait->accpet->epoll_ctl调用,而使用select只需要select->accpet,减少了一次系统调用。读写密集的话,如果收到数据,我们需要响应数据的话,使用epoll的情况下, read 完后也需要epoll_ctl 加入写事件,相比select多了一次系统调用。所以 在连接数多且不活跃下,epoll比较高效。连接数少且都很活跃下,select比较高效。io特别密集时为什么 epoll 效率不高。

2023-08-10 22:02:57 267

原创 MySQL的加锁原则

优化 2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock 退化为间隙锁。优化 1:索引上的等值查询,给唯一索引加锁的时候,next-key lock 退化为行锁。原则 1:加锁的基本单位是 next-key lock。是一个前开后闭区间。一个 bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止。原则 2:查找过程中访问到的对象才会加锁。

2023-08-02 20:50:10 89

原创 一个 SQL 执行的很慢

(1)、没有用上索引:例如该字段没有索引;由于对字段进行运算、函数操作导致无法用索引。(1)、数据库在刷新脏页,例如 redo log 写满了需要同步到磁盘。2、这条 SQL 语句一直执行的很慢,则有如下原因。1、大多数情况下很正常,偶尔很慢,则有如下原因。(2)、执行的时候,遇到锁,如表锁、行锁。(2)、数据库选错了索引。

2023-08-02 20:36:47 143

原创 mysql数据库自增ID用完了会怎么样?

表尽可能都要设置主键,主键尽量使用bigint类型,21亿的上限还是有可能达到的,比如魔兽,虽然说row_id上限高达281万亿,但是覆盖数据显然是不可接受的。如果没有设置主键,数据库则会帮我们自动生成一个全局的row_id,新数据会覆盖老数据。如果设置了主键,那么将会报错主键冲突。

2023-08-02 16:54:38 354

原创 msql中为什么不用delete

通过从InnoDB存储空间分布,delete对性能的影响可以看到,delete物理删除既不能释放磁盘空间,而且会产生大量的碎片,导致索引频繁分裂,影响SQL执行计划的稳定性;为了实现数据归档需求,可以用采用MySQL分区表特性来实现,都是DDL操作,没有碎片产生。另外一个比较好的方案采用Clickhouse,对有生命周期的数据表可以使用Clickhouse存储,利用其TTL特性实现无效数据自动清理。同时在碎片回收时,会耗用大量的CPU,磁盘空间,影响表上正常的DML操作。

2023-08-01 22:29:27 103

原创 mysql中6中索引失效问题

如果字符串是索引列,而条件语句中的输入参数是数字的话,那么索引列会发生隐式类型转换,由于隐式类型转换是通过 CAST 函数实现的,等同于对索引列使用了函数,所以就会导致索引失效。在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。联合索引要能正确使用需要遵循最左匹配原则,也就是按照最左优先的方式进行索引的匹配,否则就会导致索引失效。当我们在查询条件中对索引列进行表达式计算,也是无法走索引的。当我们在查询条件中对索引列使用函数,就会导致索引失效。

2023-08-01 21:21:53 231

原创 redis突然变慢问题定位

内存相关:bigkey 内存的申请和释放、数据过期、数据淘汰、碎片整理、内存大页、内存写时复制都与内存息息相关。CPU 相关:使用复杂度过高命令、数据的持久化,都与耗费过多的 CPU 资源有关。操作系统:写时复制、内存大页、Swap、CPU 绑定,都属于操作系统层面的知识。网络相关:短连接、实例流量过载、网络流量过载,也会降低 Redis 性能。计算机系统:CPU 结构、内存分配,都属于最基础的计算机系统知识。磁盘相关:数据持久化、AOF 刷盘策略,也会受到磁盘的影响。

2023-07-29 22:04:56 568

原创 redis常见面试汇总

redis常见面试汇总

2023-07-29 21:13:24 782

原创 redis之Bitmap

命令用于统计给定位数组中值为1的二进制位的数量。功能似乎不复杂,但实际上要高效地实现这个命令并不容易,需要用到一些精巧的算法。指定 中的了,接下来就要计算在8个字节中的第几位呢?3.二进制位统计算法:variable-precision SWAR。),byte 值表示指定的 位于位数组的哪个字节(计算在第几行);根据 和 在位数组中定位到目标值返回即可。算法,该算法通过一系列位移和位运算操作,可以。用于返回位数组在偏移量上的二进制位的值。目前已知效率最好的通用算法为。

2023-07-29 17:31:51 529

原创 redis分布式锁

Redis 作者继续论述,如果对方认为,发生网络延迟、进程 GC 是在步骤 3 之后,也就是客户端确认拿到了锁,去操作共享资源的途中发生了问题,导致锁失效,那这。

2023-07-29 16:56:25 294

原创 redis数据结构

C语言字符串底层也是一个数组,每次创建的时候就创建一个N+1长度的字符。Redis为了避免C字符串这样的缺陷,就分别采用了两种解决方案:1空间预分配。C是不记录字符串长度的,一旦我们调用了拼接的函数,如果没有提前计算好内存,是会产生缓存区溢出的。SDS结构存储了当前长度,还有free未使用的长度。SDS自己本身就保存了长度的信息。

2023-07-28 20:48:02 211

原创 HTTP协议各自特点

HTTP/2 是基于 TCP 协议来传输数据的,TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且连续的,这样内核才会将缓冲区里的数据返回给 HTTP 应用,那么当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核缓冲区里,只有等到这 1 个字节数据到达时,HTTP/2 应用层才能从内核中拿到数据,这就是 HTTP/2 队头阻塞问题。QUIC 有以下 3 个特点。HTTP/2 有什么缺陷?

2023-07-28 16:53:38 388

原创 GO语言栈内存空间管理

栈分配: 编译器+runtime结合实现。编译器会在函数头部安插检查栈大小是否够用代码,不够则调用runtime栈增长的函数。开辟个更大的--拷贝数据--释放原来的 唯一会收缩的地方就是GC。收缩完后再让出CPU。 协成运行结束时, 栈释放到哪里了呢?

2023-07-20 15:20:54 127

原创 Go语言mallocgc

runtime中new和make都依赖mallocgc。mallocgc分为4个阶段:辅助GC,空间分配,位图标记,收尾工作。

2023-07-20 15:01:18 159

原创 GO语言泛型

也就是泛型会为每个数据类型都生产一套代码,导致可执行文件大小增加,并且使用泛型。但是使用GET 需要使用类型断言,将取出来的数据转为预期数据,空接口本身是一个装箱,会产生内存逃逸和多一部分空间.缓存对象存储多个不同类型的值依然要用空接口,否则。于是1.17GO使用泛型.缓存对象只能存一种类型的值。set一般没什么不方便的。分析可执行文件后:发现。

2023-07-19 17:11:35 968

原创 GO语言方法集

因为我们A(a)接受者是第一个参数,而这个参数是动态派发的,参数放在栈的局部变量,编译器在编译阶段不能确定这个量的大小.而指针平台确定了大小也就确定了.面对这个问题,编译器选择为值接受方法生成指针同名方法。那为什么还要生产包装方法呢?主要是为了支持接口.

2023-07-19 15:56:54 309

原创 GO语言semaphore信号量

本质上.是结合自旋锁和调度器调度后的锁.不过这种机制适合线程不适合协程.因为调度器调度需要切换线程,而协成切换不能切换线程.一般地,我们唤醒在等待队列中的线程会使用系统调用和切换线程这样的开销比较大.在GO语言中,我们使用semaphore协程信号量来排队。协程等待一个锁如何等待和唤醒呢?

2023-07-19 15:40:06 522

原创 GO语言Metex

尝试加锁的G会先自旋几次,若获不到锁,则加入等待队列. 正常模式下,自选和等待队列的一起竞争。在多核下,,且至少有一个其他的P在running,且当前P的本地队列为空才可以自旋转.自旋的条件,当单核下自旋没意义,或者只有一个P时自旋也没意义.因为G频繁的挂起和唤醒会导致开销,为了高吞吐。前面其他位表示多少个等待者。直接加入等待队列FIFO。

2023-07-19 15:22:45 442

原创 GO 语言GC

2.每次内存分配都会检查是否需要辅助标记.到GC清扫阶段,内存分配就会促发辅助清扫.例如,分配一个span,若这个span尚未清扫,则需要清扫完再使用.辅助标记和辅助清扫可以避免并发垃圾回收中内存过大的分配压力导致来不及清扫。确定是存活指针还要确定是否指向堆内存:,如果指向堆内存,则把他们加入到GC中进一步扫描.1.若协程需要申请内存,而GC尚未完成,则协程需要当任部分GC工作,借贷尝还机制.写屏障是在写操作中插入指令,目的是把数据对象的修改通知到GC。实现强弱三色不式,为了避免误删,则实现写屏障.

2023-07-18 23:35:39 986

原创 GO语言GMP模型

3,信号量,.当检测到信号后,注入一个异步抢占函数调用,处理完信号后返回立刻执行被注入的异步抢占函数,而这个函数就有schedul逻辑 1.14。5,最后再次 本地G, 全局G,netpoll,steal from other p ..若是别人的G则要看看这个G是否有绑定的M.创建一个协程主要是调用newproc函数,而newproc函数是在G0创建的,为什么是G0?创建完新G(协程栈)后,会赋状态Grunnable,.表示可以运行的G..于是看情况调度到别的P。4,全局G调度部分到本地G。

2023-07-18 22:15:27 997

原创 GO语言reflect

GO语言中参数为空接口,下面这种写法:

2023-07-18 19:38:51 72

原创 GO语言类型系统,接口,类型断言

每种类型都有对应的类型元数据,而类型定义的方法通过类型元数据找到。注意:别名是别名 ,自定义类型是自定义类型。

2023-07-18 14:53:32 193

原创 GO语言方法

本质 方法表达式和方法变量都是funcval。

2023-07-18 00:18:32 72

原创 GO语言闭包

函数的指令在编译期间生产,但是function value并不直接指向函数指令入口,而是指向runtime.funcval结构体。这个结构体只有一个地址,就是函数指令的入口地址。闭包:1 必须在函数外部定义,但在函数内部自由调用的变量。2,脱离形成闭包的上下文,也能照常运行。指向funcval,用一个二级指针来调用,这是为了解决闭包问题。其中,GO语言通过寄存器DX得到funcval结构体地址。闭包导致局部变量逃逸到堆。

2023-07-17 23:34:45 131

原创 GO语言slice

3,各种语言从OS上提前申请内存,匹配GO规则的内存。2,预估容量后*字节数 = 所需的内存。以及存取的元素是可以安全读写的。

2023-07-17 21:48:36 158

原创 GO语言String

String GO语言认为不可以修改。若想要改,可以重新复制,或者改为([]byte)类型。一个String: data+len(字节数)

2023-07-17 21:36:03 64

原创 最大并发TCP链接

7.表示系统同时保持TIME_WAIT的最大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息。6,表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。允许将TIME-WAIT sockets重新用于新的TCP连接。4,表示开启TCP连接中TIME-WAIT sockets的快速回收。5,修改系統默认的 TIMEOUT 时间。2,开启SYN Cookies。1,提高整个系统的文件限制。

2023-07-16 23:05:40 112

原创 TCP三次握手调优

TCP3次握手优化

2023-07-16 22:57:53 436

原创 TCP缓冲区和4次挥手调优

TCP缓冲区和4次挥手调优

2023-07-16 22:31:25 1468

原创 QUIC协议原理分析

一条 TCP 连接 [17] 是由四元组标识的(源 IP,源端口,目的 IP,目的端口)。所以 QUIC 协议选择了 UDP,因为 UDP 本身没有连接的概念,不需要三次握手,优化了连接建立的握手延迟,同时在应用程序层面实现了 TCP 的可靠性,TLS 的安全性和 HTTP2 的并发性,只需要用户端和服务端的应用程序支持 QUIC 协议,完全避开了操作系统和中间设备的限制。TCP 使用序列号来标识数据的顺序,数据必须按照顺序处理,如果前面的数据丢失,后面的数据就算到达了也不会通知应用层来处理。

2023-07-14 22:22:17 713

原创 HTTP1和HTTP2和HTTP3的区别

超文本传输协议是一个简单的请求-响应协议,它通常运行在TCP之上。

2023-07-14 21:40:20 588

原创 Space Saving算法

在实际应用中,SpaceSaving算法通常能够提供足够准确的结果,尤其是对于大规模数据集。如果元素不在集合中且集合已满,将集合内计数器值最小的元素移除,将新元素插入到它的位置,并且在原计数值的基础上自增。集合中最小的计数值min一定不会大于m / k = εm(m个元素中,数量超过m/k的元素),同时能够保证找出所有频率大于εm的元素;可见,Space Saving算法构建在Misra-Gries算法的基础上,。如果元素不在集合中且集合未满,就将元素加入集合,计数器设为1;准确率取决于计数器大小。

2023-07-13 16:06:44 849

原创 一个HTTP的流程

一个HTTP的流程

2023-07-10 22:19:59 698

原创 当你按下键盘A键

CPU 里面的内存接口,直接和系统总线通信,然后系统总线再接入一个 I/O 桥接器,这个 I/O 桥接器,另一边接入了内存总线,使得 CPU 和内存通信。再另一边,又接入了一个 I/O 总线,用来连接 I/O 设备,比如键盘、显示器等。那当用户输入了键盘字符,就会产生扫描码数据,并将其缓冲在键盘控制器的寄存器中,紧接着键盘控制器通过总线给 CPU 发送。CPU 收到中断请求后,操作系统会,然后调用键盘的。键盘的中断处理程序是在初始化时注册的,那键盘。

2023-07-09 22:32:54 1447

原创 Linus I/O之io_ring

由于调用系统调用时,会从用户态切换到内核态,从而进行上下文切换,而上下文切换会消耗一定的 CPU 时间。:I/O 请求完成后,SQ内核线程会将 I/O 请求的结果写入到。为了减少或者摒弃系统调用,采用了用户态与内核态。:SQ内核线程发起 I/O 请求。中读取到 I/O 操作的结果。中读取 I/O 操作。提交 I/O 操作。:应用程序可以通过从。

2023-07-09 20:45:22 403

原创 Linux 内核级通用内存池 —— kmalloc 体系

当申请内存块的尺寸超过 192 字节时,内核会通过 fls 函数来计算 kmalloc_info 数组中的通用 slab cache 索引。

2023-07-09 19:50:34 542

原创 slab 内存池的设计与实现

伙伴系统内存分配原理的相关内容来看,。也就是说,当我们向伙伴系统申请内存时,至少要申请一个物理内存页。内核实际运行过程中来看,无论是从内核态还是从用户态的角度来说,对于内存的需求量往往是以字节为单位,通常是几十字节到几百字节不等,远远小于一个页面的大小。如果我们仅仅为了这几十字节的内存需求,而专门为其分配一整个内存页面,这无疑是对宝贵内存资源的一种巨大浪费。于是在内核中,这种专门针对小内存的分配需求就应运而生了,而本文的主题—— slab 内存池就是专门应对小内存频繁的分配和释放的场景的。

2023-07-03 22:55:58 612

空空如也

空空如也

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

TA关注的人

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