自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 elasticsearch是如何进行搜索的?

以 TF - IDF 为例,如果文档中某个词出现的频率高(词频高),但在整个语料库(索引中的所有文档集合)中该词比较少见(逆文档频率高),那么这个词所在的文档相关性得分就会相对较高。例如,在一个美食相关的索引中,如果 “全聚德烤鸭” 这个词在某篇介绍全聚德的文档中多次出现,而在其他文档中很少出现,那这篇文档在以 “烤鸭” 为查询词时相关性得分就会比较高。是一个不变的、独立的倒排索引,储存了文档的字段、倒排表、储存字段以及其他索引元数据。分片会从它的所有 Segment 中收集匹配的文档,并按相关性排序。

2024-12-03 21:49:34 516

原创 Redis集群节点如果出现故障了,会如何处理呢?

此外在哨兵故障检测之外还存有节点自检,目的在于确保节点间通信正常,维护集群状态。以保证其他主节点知晓该主节点已经下线,并且防止从节点同时启动选举。如果手动配置新主节点或者槽迁移恰好碰上了故障选举,使得同一选举期存在多个主节点,那么该如何处理冲突呢?从节点会计算选举期,若获取的票不在本轮选举中,则不会进行计数。NodeID字典序更小的节点将成为唯一的主节点,并递增选举期。若故障节点为主节点,集群尝试从主节点的从节点中选取新主节点。会不会存在一个从节点收到了同主节点的两轮选举的投票呢?主节点在投票一次后,在。

2024-11-23 15:17:48 676

原创 设计excel导入的思考

excel导入就是将excel里面的数据转换组织形式,对数据库表进行映射更改。

2024-10-22 23:45:00 979 1

原创 本地缓存少更改、小数据、低一致表的思考

对于那些少更改、小数据的表,以及对一致性要求不高的业务,其实完全可以通过本地缓存将表数据缓存到本地内存中,然后通过定时机制拉取表更新数据直接从内存中获取数据,将会使得查询性能得到巨大的提升,并且由于更改少,数据量小,同时内存压力也不会很大,除了一致性不高外,完全是利大于弊的策略那么如果我想设计这样的本地缓存,该如何进行呢?

2024-10-21 23:53:35 458

原创 从automaxprocs库浅窥Linux容器的资源控制

automaxprocs能够自动调整Go程序中的Goroutine数量,以充分利用系统资源并提高程序的性能。automaxprocs通过读取系统信息,如CPU核心数和Cgroups限制,来动态调整Goroutine的数量automaxprocs获取CPU限额的关键方法在可以看到是先获取到cgroup的实现,然后调用实现方法获取限制获取cgroup2实现如下具体算限制方法如下其实就是取cpu.max文件中指定的限额。

2024-10-11 22:51:40 950

原创 mysql json查询为什么这么快?

在本地测试中我发现了一件令我惊讶的事情,在300w数据量对json字段里面值进行筛选的时间都在100ms左右!那么为什么mysql json查询这么快呢?

2024-09-01 12:23:23 624

原创 如何设计数据库排序字段

在很少会有中间插入或者对查询排序有较高要求的情况:较短间隔的int是更优的方法在中间插入情况较多的时候:可能float类型更为合适链表方法在插入情况较多的时候也是非常适用的,可是查询性能属实太差数据量少:可以用配置文件或者直接在缓存中设置排序。

2024-08-31 09:52:18 452

原创 GO goroutine状态流转

go池是所有拥有goroutine的地方,包括P的runnext、P本地队列和全局队列Gidle -> Grunnable: 初始化g,放入go池Grunnable -> Grunning: 从go池取出,绑定M,执行实际代码Grunning-> Gdead: 解绑M,重置g,重新放入go池-> Gwaiting: 解绑M,等待被唤醒-> Grunnable: 解绑M,放入go全局队列Gwaiting -> Grunable: 被唤醒后放入go池。

2024-08-01 22:42:20 1038

原创 go内存返还系统相关代码

在go中内存返还系统相关代码主要由sysUnusedOS实现在Linux中默认是通过madvice方法的_MADV_FREE进行释放,在这种释放中内存其实是被延迟回收的。sysUnusedOS被scavengeOne调用,scavengeOne在给定的内存块(chunk)中搜索可回收的连续页面,并尝试回收指定数量的内存值得注意的是,在回收之后内存还是可以再次分配的scavengeOne继而被scavenge调用该过程分块进行,从最高地址开始,一直持续到清除指定字节数(nbytes)或耗尽堆。

2024-07-05 21:00:00 842

原创 Golang栈空间管理

连续栈核心原理是当当前栈内存不足时,会触发中断,从而分配更大充足的栈空间,并迁移原栈内容到新栈。此外,除了扩容,连续栈还会在已使用的栈空间未超过了总可用空间的四分之一,将新栈收缩到原来的一半。在Go1.3之前,所有goroutine在初始化时都会分配一块固定大小的内存空间。分段栈能够按需为当前goroutine分配内存,并及时减少内存占用,但。迁移过程会被指针也同样迁移过来,不过没关系根据逃逸分析不变性——,所以指向栈中变量的指针只能在栈上。与堆类似,栈也有全局和局部栈空间。

2024-07-05 20:30:00 354

原创 Go堆内存管理

heapArena: heapArena 是由 mheap 管理的更小的内存块。按 Span class 对 Span 分类,串联成链表,当 mcache 的某个级别 Span 的内存被分配光时,它会向 mcentral 申请 1 个当前级别的 Span。微分配器将多个微小块分配请求合并到同一个内存块中,只有当内存块中的所有对象都需要被回收时,整片内存才可能被回收。mcache: 每个P所有的cache,包含多个空闲内存块链表,不同的链表上的内存块大小可能是不相同的。Go按照不同对象大小有不同的分配逻辑。

2024-07-05 14:48:04 886

原创 Linux文件数据写入

结构体fdfd也就是文件描述符,用于标识已经打开的文件、管道、socket等。是进程和内核的桥梁,允许进程执行各种文件操作struct fd { struct file *file; unsigned int flags;};fileLinux内核中表示打开文件的结构体,包含了文件操作所需的各种信息和元数据。这是文件系统操作的核心结构之一,允许内核跟踪每个打开的文件及其相关的状态。struct file { // 用于链接或者引用计数 union { // 链表节点

2024-07-02 22:45:00 1536

原创 Linux自旋锁

面对没有获取锁的现场,通常有两种处理方式。本文主要讲述自旋锁自旋锁其实是一种很乐观的锁,他认为只要再等一下下锁便能释放,避免了操作系统进程调度和线程切换。

2024-06-17 21:15:00 1399

原创 go string 实现

在go中string是不可变的,这意味着对string发生改变的操作实际上都是通过分配新的string去实现的在string内存分配上,对于小对象分配到栈,大对象分配到堆中string在go中的结构其实很简单,就是一个指向实际数据的指针以及字符串的长度。

2024-05-24 17:53:45 405

原创 golang http2客户端处理逻辑分析

流的状态会随着帧(Frame)的发送和接收而改变。客户端连接通过判断是否超出最大并发流限制去创建新流处理,一个请求通过是否有可复用的客户端连接来判断是否要重新创建,而流是不能被复用的。连接池中不存在已经建立的连接,或者连接不能再承载新请求了(比如已经创建的流数量+等待的请求*2已经超过了int32的最大值)客户端连接在创建之后,开启新协程,从帧处理器循环读取帧,流的缓存管道绑定响应体后,数据被添加到对应流的缓存管道中。一个客户端连接对应一个网络连接,一个客户端连接对应多个流,而一个请求对应一个流。

2024-05-17 14:01:25 1140 1

原创 单核CPU调度

相反,如果一个任务“想”在一个配额的时间片上使用更多的内核,它就会在短时间内使用多于配额的内核,然后进入节流状态,也就是说基本上进入睡眠状态,以保持它的摊销内核使用量低于配额,这对于尾延迟来说是灾难性的。调度类是表示一种特定的调度策略和算法,定义了如何选择下一个要运行的任务,如何将任务插入到运行队列中,以及如何处理任务的唤醒和睡眠等。CFS调度利用红黑树优先调度执行总时间更低的,在每次时间片执行完会对执行的进程累加执行时间,并重新选择最低执行时间的进程进行执行。这也就意味着执行越久,执行优先级越低。

2024-05-12 09:14:41 771

原创 golang testing使用

汇报自定义度量值如果度量值是每次迭代的,你应该将其除以b.N。按照惯例,单位应该以 “/op” 结尾。会覆盖同一单位的任何先前报告的值。如果单位是空字符串,或者单位包含任何空格,会引发 panic。如果单位是基准测试框架本身通常报告的单位(如 “allocs/op”),会覆盖该度量值。将 “ns/op” 设置为 0 将禁止该内置度量值。for i := 0;i < b.N;

2024-05-07 21:15:00 1100

原创 golang 随机数演化

Source接口定义为缩短的63位,这并不是现代生成器的uint64。

2024-05-07 20:15:00 648

原创 golang netpoller揭秘

netpoller依托于go调度器,提供了一种看上去同步的异步网络编程模式,显著地降低了开发难度更重要的是,go主动挂起goroutine等待网络IO的完成,而不是被动让系统线程去挂起,这就将执行网络IO的goroutine掌控在Go运行时中。

2024-04-28 22:30:00 731 1

原创 golang sync pool

sync.Pool是内置对象池技术,可用于缓存临时对象,避免因频繁建立临时对象所带来的消耗以及对GC造成的压力在很多知名框架中都可以看到sync.Pool的大量使用。比如Gin中用sync.Pool来复用每个请求都会创建的对象但是值得注意的是sync.Pool缓存的对象可能被无通知的清理。

2024-04-25 15:04:37 1092 1

原创 VLL: a lock manager redesign for main memory database systems阅读

VLL锁管理结构由储存到每个原始数据的的未完成锁写请求数量CX和未完成锁读请求数量CS中心事务请求全局队列TxnQueue组成。

2024-04-12 18:20:06 519

原创 KMP算法理解

之所以储存下一个的原因在于,在进行匹配时,模式串要跳到上一个匹配成功的位置,而字符串本身不会移动,那么在这种情况下,当前字符串要匹配的就是已经匹配成功字符的下一个位置。比如对于字符串"abab",其前缀有a、ab、aba,后缀有b、ab、bab,显然最长公共前后缀就是ab。next[i]储存了在以i为开头的后缀,和以j为结尾的前缀匹配时,j的下一个位置。正如next名字所暗示的,下一个,而不是匹配的j本身。在获取到next数组之后,就直接获取到了如果不匹配情况下,模式串该如何走。

2024-03-26 18:13:29 289

原创 如何实时计算数据流中位数

创建一个最小堆和最大堆,其中最小堆的最小值比最大堆的最大值还大,并使最小堆最大堆数量保持均衡,那么中位数边取乎于最小最大堆堆顶。最容易想到的思路就是直接将所有数据进行排序,然后取排序之后的中位数。不过具体的排序思路也有几种。

2024-03-18 11:42:44 463

原创 Mysql 数据如何储存?

我们知道varchar类型的列最多允许65535字节,在允许NULL的情况下最多储存65532字节,因为NULL标识符占1字节,真实长度数量占2字节。此外,65532这个限制是所有varchar列的长度总和,也就是如果存在多个varchar字段,虽然单个没有超出限制,但这多个字段如果合起来超出了限制,那还是会无法创建的。之所以是记录到下条真实数据的偏移量,而不是下条数据偏移量的原因在于可以利用局部性将前面数据的逆序储存的字段长度、NULL值列表缓存起来,减少数据再次查询硬盘次数。

2024-03-18 11:40:35 1913

原创 PacificA: Replication in Log-Based Distributed Storage Systems阅读

PacificA是微软实现的强一致性的分布式共识协议,用于局域网中基于log的大规模储存系统遵循以下原则有以下前提条件系统仅发生fail-stop错误fail-stop是系统组件仅停止运行,而没有其他额外的错误行为消息可能丢弃或者重排,但不会被修改网络分区也可能发生不同服务器上的时钟不一定同步,甚至不一定是松散同步的,但是时间漂移有上限。

2024-02-23 18:50:39 936

原创 kafka 生产者消费者设计思考

如果采用消费者ack的模式,也就是消费者消费完成之后发送确定消息,那么如果消费者在发送ack的时候也失败了,这就会导致重复消费问题。很可惜,kafka最多只能支撑生产者不发送重复的消息,如果是上述场景中消费者没有ack成功导致的重复消费,还是要进行额外幂等处理的。如果broker在发送消息后,立刻认为消息已经被消费了,那么在传输未到达等原因引发的消费未处理情况会使得这样的认为并不正确。为了避免这些问题,kafka将消息划分到有序的分区中,那么只要记录每个分区被每个消费者组消费数据即可。

2024-02-22 15:08:00 750

原创 文档协作技术——Operational Transformations简单了解

OT是支持协作软件系统的一种广泛使用的技术。OT通常使用副本文档储存,每个客户端都拥有对文档的副本。客户端在本地副本以无锁非堵塞方式操作,并将改变传递到其他客户端。当客户端收到其他客户端传播的改变之后,通过转换应用更改,从而保证一致性初始文档为"abc",并存在客户端A、BA发起操作O1=insert[0, “x”],在位置0插入字符xB发起操作O2=delete[2, “c”],在位置2删除字符c。

2024-02-07 15:09:46 1145 1

原创 algo-桶排序

桶排序是一种分布排序,将元素数组分到多个桶内,然后每个桶再分别进行排序。其计算复杂度取决于对桶内排序所用算法、使用桶数量以及输入均匀度。主要流程如下。

2024-02-04 18:05:04 969

原创 golang sudog是什么?

sudog代表在等待队列中的goroutine,比如channel发送接受。由于goroutine和同步对象的关系是多对多,因此需要sudog映射。

2024-02-02 15:34:03 1076

原创 sync.Cond 源码分析

sync.Cond采用一个L锁进行保护条件变量,并使用通知队列来堵塞和通知goroutine。

2024-02-02 15:30:51 471

原创 为什么golang不支持可重入锁呢?

而其他需要用到的场景,可以通过参数控制是否加锁、或者将递归调用函数提取到新函数中交予新函数加锁、或者采用channel之类的来迂回达成可重入锁的目的。那么在实际开发工程中就可能存在虽然是同一个goroutine运行,但是在一个方法内很难知道其他方法是否也用了这个锁,用来做什么。那么重入锁在此时便无法保证保护不变量。比如说存在两个接口方法A、B,A中调用了B,但是由于这两个方法都可能被其他方法所调用,所以如果没有可重入锁便可能会死锁。在工程中使用锁的原因在于为了保护不变量,也可以用于保护内、外部的不变量。

2024-02-01 18:22:24 1231

原创 algo-水塘抽样

水塘抽样是一组随机算法,通过替换k个样本,从未知大小的n个总体中选择随机样本。

2024-02-01 16:29:30 869

原创 Redis锁的使用姿势

考虑到redis主从同步集群中,如果从master获取到锁之后,就故障换成了从节点,那么就会导致锁失效,因此提出了RedLock的分布式锁算法。该算法依赖于这样的假设:虽然进程之间没有同步时钟,但每个进程中的本地时间几乎以相同的速率更新,与锁的自动释放时间相比,误差很小。在上述锁中,存在一个问题——如果A获取了锁,但是由于执行时间过长,导致B也获取到过期后的锁,此时并会同时存在多方获取锁。以下是删除特定value的锁的lua脚本,这样就可以防止删除不属于自己的锁。在锁竞争比较激烈情况下,性能损耗较大。

2024-02-01 16:07:44 442

原创 Redis stream特性了解

在发布订阅中我们了解到发布订阅模式存在的无法持久化保存消息和对于离线重连的客户端不能读取历史消息的缺陷,以下就来了解一下stream是如何解决这个问题的steam是类似于仅添加log的数据结构,提供了以下基本命令XADD: 添加新条目到streamXREAD: 读取条目XDEL: 根据id删除消息DEL: 删除streamdel skeyXRANGE: 返回范围内的条目XLEN: 返回流的长度xlen skeyXINFO: 展示stream的信息。

2024-02-01 11:26:08 924

原创 Redis发布订阅怎么用?

而基于模式的订阅是通过pubsub_patterns的链表去实现的。订阅时创建包含客户端信息和模式的pubsub_patterns,并添加到链表中。发布订阅的实现其实是通过key为频道value为储存订阅频道客户端的字典的链表去实现的,发布时直接遍历所在频道的链表进行消息发送。在发布时,就会遍历该链表检查是否匹配模式,然后发送消息给匹配客户端。

2024-01-29 19:07:09 541

原创 golang map真有那么随机吗?——map遍历研究

在随机选取map中元素时,本想用map遍历的方式来返回,但是却并没有通过测试。那么难道map的遍历并不是那么的随机吗?以下代码参考go1.18hiter是map遍历的结构,主要记录了当前遍历的元素、开始位置等来完成整个遍历过程mapiterinit为开始遍历的方法,主要是确定初始遍历的位置从上面的代码分析我们便可以看出随机选取的元素并不是真的随机,溢出桶并不包含在随机选择的范围里面在具体的遍历过程,存在以下疑问通过以上代码分析,可以看出:在扩容时遍历,如果当前遍历的桶已经迁移好了,那么取新桶。

2024-01-25 22:45:00 1160

原创 什么是线段树?

线段树是用于储存区间信息的数据结构。线段树将区间划分为左右子区间进行递归求解,便形成了树形结构。并通过合并两区间信息从而取得任意区间信息例如对于数组a={10, 11, 12, 13, 14},那么就可以构建以下线段树。

2024-01-23 19:10:21 508

原创 Mysql如何快速插入10亿条数据呢?

若一组任务堆积量太大,或者堆积时间太长,则让其他工作节点每处理完一批本组数据,便要处理该堆积数据,直到该堆积数据低于阈值量或者阈值时间。设置一个批次插入为一个任务,在此定每次插入1000条数据,那么每个文件总共就是1w个任务,这1w个任务便为一个任务组。工作节点收到数据后,连接数据库,根据负载情况开启多线程对所接收任务,以任务ID组合行数作为表id进行插入数据。工作节点完成本节点绑定的所有任务之后,便可以开始抢占其他节点任务,以未完成量最多的任务组为优先。超过该任务数,进行抢占其他任务组或者等待。

2024-01-23 19:06:11 1040

原创 基数排序简单了解

基数排序是根据数字每一位从低到高去进行分类排序的比如对于数组[1, 11, 2, 12],从个位数开始,1和11分到了桶1,2和12分到了桶二,接着十位数,1和2分到了一桶,但由于在上一次分桶中,2在1之后,所以这个顺序仍然会保留,11和12也是一样,因此最后得到正确的有序数组[1, 2, 11, 12]

2023-12-06 15:05:05 163

原创 algo-多数排序

多数排序在leetcode只是一个简单题,但是衍生出来的多种解法却非常有意思首先是最容易想到的hash和排序算法,接着是。

2023-12-06 14:21:09 147

空空如也

空空如也

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

TA关注的人

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