自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(59)
  • 资源 (1)
  • 收藏
  • 关注

原创 Mysql锁机制 - 各种SQL语句的加锁方式

各种SQL的加锁方式

2022-10-22 16:19:45 2492 1

原创 Mysql锁机制 - 锁类型

Innodb各种锁类型介绍

2022-10-16 18:36:36 831

原创 Golang应用专题 - channel

1、channel的初始化2、channel的关闭3、channel的数据统计当初始化channel不指定通道容量(或指定容量为0)时,该通道为无缓冲channel;1、无缓冲channel的特性2、无缓冲channel的用途3、goroutine泄露当无缓冲channel的发送者goroutine数量和接受者goroutine数量不一致时,会导致较多一方的goroutine阻塞,且无法自动回收(goroutine不会自动被回收),造成goroutine泄露当初始化channel时指定通道容量,该通道为有

2022-06-25 20:24:31 1030

原创 记一次go-panic引发的消息堆积

背景业务上使用生产-消费模式处理第三方上报的异步消息;job服务作为消费者,以常驻线程的方式,统一消费各个topic的消息(业务使用kafka做消息队列),然后通过同步调用业务接口使消息生效,数据流大致如下:一条异常消息引发的惨案一天中午,在uat环境出现队列消息堆积、数据无写入的现象,快速定位到job-service服务容器一直处于重启中,无法正常工作;通过重启日志,发现一个topic的消费者在消费某条消息时panic,导致整个job服务宕机,虽然discovery服务检测到心跳异常后不断重启,但

2022-05-22 17:03:50 791

原创 Golang -内存管理

内存分配Golang在程序启动时预先向操作系统申请内存,包括:arena即堆区,应用中需要的内存都从这里分配,大小为512G为了方便内存的管理,arena区内存被分成一个个的page,页, 每个页大小为8KB, 整个arena共512G / 8K = 64M个页bitmap即位图区,存放内存管理中所有的位图信息16G?spans即所有已创建的span的指针列表(下文会介绍span的概念和功能)每个Span指向一个page,故spans大小为64M * 8B = 512MB;

2022-05-02 16:58:49 1283

原创 Golang - GMP模型

线程池的缺陷我们以网络模型为例。互联网早起的网络模型有PPC和TPC:PPC: 即Process Per Connection, 每个网络连接都新fork一个进程来处理TPC: 即Thread Per Connection, 每个网络连接都新建一个线程来处理不管是fork进程还是新建线程,都存在较大的系统开销(线程相对更小),于是工程师们想到了PreFork和PreThread网络模型:PreFork, 即预先创建好进程,新网络连接到来之后直接使用之前新建的进程,而不用临时创建,降低网络请求

2022-04-23 23:13:40 2722

原创 每个程序员都应该了解的内存知识(简要笔记,持续更新)

目录RAM类型静态RAM动态RAMDRAM访问细节CPU高速缓存高速缓存的位置高速缓存的操作缓存操作类型参考文献地址(中文翻译)RAM类型RAM类型主要分为静态RAM(SRAM)和动态RAM(DRAM),两者功能相同,但是SRAM更快,与之对应价格更贵静态RAM一个单元有6个晶体管 => 结构复杂,成本和实现难度更大状态稳定,可以快速在两个稳定状态(0/1)转换动态RAM一个单元只有一个晶体管和一个电容器,结构简单,成本和实现难度更低状态读取依赖电容充放电,需要花时间等待,所以

2022-04-17 18:55:57 1534

原创 内存管理和虚拟内存

内存管理存储器的抽象—地址空间物理地址直接暴露给进程带来几个严重的问题假如用户程序可以寻址内存的每一个字节,它们就可以很容易的破坏操作系统并行多个程序成为困难,程序访问相同的地址会造成彼此数据的破坏地址空间地址空间是一个进程可用于寻址内存的一套地址集合,每一个进程都有一个自己的地址空间,并且这个地址空间独立于其他进程的地址空间。基址寄存器和界限寄存器动态重定位: 使用基址寄存器和界限寄存器将每个进程的地址空间映射到物理内存的不同部分比如一个16K的程序被装载到内存,基址寄存器会记录程

2022-04-17 18:52:15 3157

原创 架构设计思考-2

架构设计原则架构设计需要遵循的三大原则:合适原则、简单原则、演化原则合适原则合适优于业界领先举个栗子,几个人规模的团队想做一个类似QQ的“亿级用户平台”,最终会导致整个项目的开发和后续的迭代成为灾难,主要有三个原因:没那么多人,却想干那么多活,是失败的第一个主要原因没有那么多积累,却想一步登天,是失败的第二个主要原因没有那么卓越的业务场景,却幻想灵光一闪成为天才,是失败的第三个主要原因真正优秀的架构都是在企业当前人力、条件、业务等各种约束下设计出来的,能够合理地将资源整合在一起并发挥出最

2022-04-16 16:34:05 3118

原创 TiDB基础

一些基本概念OLTP/OLAPOLTP:On-Line Transaction Processing, 在线事务处理,主要表示对数据的增删改记录某类业务的发生。如购买行为,当有订单产生后,系统需要记录何人何时何地做了什么事,要求实时性高、稳定性强、数据更新成功提供写操作的业务,一般都可以成为OLTP业务OLAP: On-Line Analytical Processing, 在线分析处理,主要表示对数据的查询当数据积累到一定程度后,需要进行数据汇总、分析、总结时,为公司决策提供数据支持

2022-03-20 23:59:49 1759

原创 架构设计思考-1

应用的服务化改造应用分层设计通常从垂直方向划分应用,分成服务层、业务逻辑层和数据层,每一层尽量做到解耦,上层依赖下层,而下层不要反向依赖上层分层涉及最怕超级数据结构,如传递一个对象,然后把这个对象一直传递下去,而且每个层都可能修改这个对象,这种做法会导致两个问题:一旦该对象修改,所有层都要进行修改无法知道该对象在哪一层被修改过,排查问题比较复杂因此,在设计接口时尽量使用原生数据类型,如int, string等大中台、小前台系统规模的发展第一阶段:单系统早期业务简单,几台机器撑起

2022-02-12 19:08:20 1967

原创 redis学习笔记 - 集群

主从复制CAP原理C: Consistent,一致性强一致性:更新之后的数据,后续的访问都能看到(CAP中默认为强一致性)弱一致性:更新之后的数据,可以允许部分或者全部访问不到(所有非强一致性的,都可以称为弱一致性)最终一致性:从节点可能暂时不能读到最新数据,但经过一段时间后,总是能追上主节点,提供一致性的结果;最终一致性是弱一致性的一种A: Availability,可用性P: Partition tolerance,分区容错性大多数分布式系统存在多个子网络,每个子网络称为一个区

2022-01-24 00:15:46 879

原创 redis专题笔记 - 跳跃列表skiplist

数据结构// 跳跃列表struct zsl { zslnode* header; // 跳跃列表的头结点 int maxLevel; // 跳跃列表当前最高层 map<string, zslnode*> ht; // hash结构所有键值对;???不太理解干啥的}// 跳跃列表节点struct zslnode { string value; // 节点值 dou

2022-01-03 17:14:37 870

原创 redis专题笔记 - 快速列表quicklist

数据结构// 快速列表数据结构struct quicklist { quicklistNode* head; // 指向快速列表头结点 quicklistNode* tail; // 快速列表尾结点 long count; // 元素总数 int node; // ziplist节点个数 int compressDepth; // 快速列表的压缩深度}// 快速列表头结点struct quicllistNode

2022-01-01 17:40:12 708

原创 redis专题笔记 - 小整数集合intset

数据结构// 小整数集合数据结构struct intset<T> { int32 encoding; // 整数位宽标识;16位、32位、64位 int32 length; // 元素个数 int<T> contents; // 整数数组,由encoding判定为16位、32位还是64位}intset的底层存储是一块连续的内存空间,其分布如下:intset数据结构的使用当set集合元素全是整数,且元素个数较少时,使用intset数据结构...

2022-01-01 16:42:33 470

原创 redis专题笔记 - 压缩列表ziplist

底层数据结构// ziplist数据结构struct ziplist { int32 zlbytes; // ziplist占用总字节数 int32 zltail_offset; // 最后一个元素距离起始位置的偏移量 int16 zllength; // 元素个数 T[] entries; // 元素内容列表 int8 zlend; // 0xFF,固定值,表示压缩列表结束位置}// ent

2021-12-31 00:59:51 728

原创 redis专题笔记 - 字典dict

底层数据结构// 字典本身数据结构struct dict { dictType *type; void *privdata; dictht ht[2]; // 2个哈希表,真正存储数据的地方;正常情况只会用其中一个,另一个在渐进式扩容时使用 int rehashidx; // 渐进式hash的进度,其他情况下为-1}// 单个哈希表数据结构struct dictht { dictEntry** table; // dictEntry指针列表

2021-12-28 23:35:10 679 1

原创 redis专题笔记 - 简单动态字符串SDS

在开始这一部分之前,首先要明确几个概念上的区别,否则容易搞混淆:面向用户的数据结构底层数据结构底层存储方式面向用户数据类型面向用户的数据类型,即我们常见的字符串、列表、哈希map等等。。。具体包括一下几类:Binary-safe strings: 二进制安全字符串Lists: 数组;字符串的集合,按照元素插入先后顺序排序Sets: 集合;字符串的集合,元素是唯一的、无排序的字符串Sorted sets: 有序集合;在集合的基础上,每个字符串元素绑定一个浮点数score,元素根据sco

2021-12-28 00:04:11 1060

原创 redis专题笔记 - 管道、事务

管道指令执行过程首先我们看一下redis客户端发送一次指令后,客户端和服务端主要做了哪些事情,如下图:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T5dZZwLb-1639903667531)(/Users/liushi/Desktop/工作/gliffy/pic/redis-send-path.jpeg)]客户端将指令包发到内核为套接字分配的发送缓冲区send buffer内核将send buffer中的数据发送到网卡设备网卡硬件将数据发送到网络经过层层路

2021-12-19 16:48:29 943

原创 redis专题笔记 - 持久化

RDB快照持久化Redis使用独立子进程进行快照持久化工作Redis是单线程程序,该线程负责监听多个客户端套接字的读写操作和内存数据的维护。快照持久化需要将内存数据全量写入磁盘,涉及大量的IO操作,如果仍然使用主线程进行,则必定阻塞正常请求RDB快照是一次全量备份,记录持久化开始那个时刻的内存数据,是内存数据的二进制序列化形式。Redis的快照持久化是基于linux系统的copy-on-write功能实现的COW传统的fork()传统的创建子进程操作,创建出的子进程和父进程共享代码段

2021-12-19 00:04:22 1144

原创 redis专题笔记 - io模型

线程IO模型同步、异步、阻塞、非阻塞关于对同步异步阻塞和非阻塞的理解,在网上看到这样一个解释,感觉说的比较明白同步阻塞:你打电话告诉老板你要买某书,老板拿起电话听你说完就去查书,没有说话,你什么也不知道,在得到任何结果之前,你一直拿着电话干等,你此时什么也干不了。30分钟后老板直接把书送到你家,这时你才挂断电话。每次电话你都要得得到结果(书到家)后你才挂断电话,这是同步。你一直拿着电话等结果,这是阻塞。同步非阻塞:你打电话告诉老板你要买某书,老板拿起电话后说“我不知道有没有货,现在去查”便挂了电话

2021-12-18 17:44:09 1203

原创 Elasticsearch - 倒排索引

在上一篇笔记Elasticsearch基础和原理中介绍了Elasticsearch的一些基本概念和原理,我们知道Elasticsearch是基于Json格式存储,每一个文档可以理解成一个json对象。这看起来和MySQL(InnoDB)完全不同的存储方式,是如何做到近乎实时检索的呢?这篇笔记就来学习一下倒排索引简单的倒排索引示例假如我们在ES中存在这样三条记录:{ "_id": 1, "log": "Oscar is fourteen years old",}{ "_id": 2, "l

2021-12-05 19:30:18 1271

原创 Elasticsearch基础和原理

目录安装和运行单节点部署基本概念和Mysql概念对比集群的概念集群状态主分片和复制分片文档文档的元数据文档的增删改查版本冲突Elasticsearch的乐观并发控制分片之间的数据同步路由主分片和复制分片的交互文档新建、索引、删除文档检索范围(分页)查询查询阶段取回阶段深度分页报错指南安装和运行本地环境使用docker部署(减少踩坑,参考官网)拉取官方镜像(采用7.15.2版本)docker pull docker.elastic.co/elasticsearch/elasticsearch:7.1

2021-11-27 21:31:11 2611

原创 kafka专题笔记 - 客户端

再均衡原理再均衡rebalance是在kafka使用中需要特别注意的一个知识点。新版kafka使用消费者协调器和组协调器对再均衡行为进行管理消费者协调器和组协调器kafka消费者客户端将全部消费组分成多个子集,每个消费组的子集在服务端对应一个GroupCoordinator对其进行管理,组协调器是kafka服务端组件;而消费者协调器ConsumerCoordinator则位于客户端的各个消费者中ConsumerCoordinator和GroupCoordinator之间最重要的职责就是负责执行消费者

2021-11-06 14:36:46 953

原创 kafka专题笔记 - 服务端

kafka协议在服务端的介绍中,首先了解下kafka协议。掌握协议不会对日常使用有太大的帮助,但是做到心中有数可以帮助我更好的理解kafka整体的运行策略。kafka中包含众多协议类型,每种类型的协议都包含请求协议Request和响应协议Response,且所有的请求协议都包相同的协议请求头RequestHeader和不同结果的协议请求体RequestBody,同理,响应协议亦是如此。下面以消息发送协议对和消息拉取协议对为例,说明kafka协议的具体实现消息发送ProducerRequest所有请

2021-11-05 00:35:04 1049

原创 kafka专题笔记 - 日志存储

文件目录布局下面以本地kafka日志文件夹为例,介绍kafka文件目录布局。kafka文件的存储目录,可以通过配置服务log.dirs确定,我本地环境使用默认的地址,log.dirs=/usr/local/var/lib/kafka-logs,进入文件夹,可以看到目前的文件内容如下:➜ kafka-logs ls__consumer_offsets-0 __consumer_offsets-22 __consumer_offsets-36

2021-10-24 23:59:42 2916

原创 kafka专题笔记 - 消费者

消费者和消费组消费者:消费kafka消息的实体,可以是一个进程,也可以是一个线程消费组:消费组是一个逻辑概念,每个消费者都隶属于一个消费组;一个消费组消费一个topic的所有消息;不同的消费组之间消费消息互补影响一个topic存在多个分区,每个分区只能被一个消费组中的某一个消费者消费消费者数量和topic分区数量的关系如下图,存在三种情况:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-119ergpM-1634991237700)(/Users/liushi/

2021-10-23 20:14:27 255

原创 kafka专题笔记 - 生产者

Producer实例构建下面的代码示例,使用sarama包创建一个producer实例import ( "fmt" "github.com/Shopify/sarama")var ( brokerList = "localhost:9092" topic = "localTestTopic" config = initConfig() producer = initProducer())// @title: initConfig// @descriptio

2021-10-21 13:39:06 620 1

原创 kafka专题笔记 - 环境配置与基础概念

安装与配置简单说下在MacOs上安装kafka的过程;后续部署环境可参考.第一步:更新brewbrew update注意:不升级可能出现 Failed to open ...13de4582463--openjdk-16.0.2.big_sur.bottle.tar.gz'的错误第二步:安装zookeeper和kafkabrew install kafkabrew install zookeeper第三步: 修改server配置文件 /usr/local/etc/kafk

2021-10-13 22:30:46 198

原创 Golang编译过程

了解编译过程的出发点,是在看一些源码的过程中,不知道内建函数的执行原理,比如:定义ch := make(chan int64, 10),在执行中到底是通过哪段源码实现的呢?基于以上疑惑,这篇笔记大致了解下Golang的编译过程几个基本概念抽象语法树ASTAST, Abstract Syntax Tree, 是源代码语法的结构的一种抽象表示,它用树状的方式表示编程语言的语法结构。编译器在执行完语法分析之后会输出一个抽象语法树,这个抽象语法树会辅助编译器进行语义分析,我们可以用它来确定语法正确的程

2021-10-10 16:29:01 435

原创 Golang源码阅读笔记 - Defer

讲到defer,首先需要了解它的使用规则,defer语句满足三个原则:defer规则1. 延迟函数的参数在defer函数出现时就已经确定下来了func test1() { i := 0 defer fmt.Println(i) i++ return}=> 打印结果为0如上实验函数1,在defer出现时延迟函数fmt.Println的参数i的值就已经确定了,此时是0;所以即便defer后更新了i的值,最终defer打印的结果仍然为0func test2(){ i := map

2021-10-01 20:33:48 216

原创 MySQL监控指标

近期在做平台压测,在分析压测结果时,发现很多MySQL监控指标不太熟悉,也了解了一些,本篇笔记记录一下Server Status VariableMySQL服务端维护了很多状态值,用以监控MySQL的运行状态,官方参考文档引用链接这里记录下常用的一些状态量Com_xxx官方解释The Com_xxx statement counter variables indicate the number of times each xxx statement has been executed. For

2021-09-29 22:49:09 653

原创 Golang源码阅读笔记 - reflect

之前在golang底层代码和业务代码中经常见到使用反射,感觉对反射的使用和理解一知半解,所以这篇笔记看下reflect底层代码的实现,加深对反射机制的理解反射包中主要包含两个文件用以描述反射涉及的功能:type.go: 类型;空接口类型描述, eface._typevalue.go: 值;空接口值描述,eface.data下面从这两个方向,分别介绍反射如何获取接口类型和接口值Typereflect.TypeOf(i interface{})可以获取反射后得到的类型变量,我们就从TypeOf(

2021-09-11 22:09:01 410

原创 Golang源码阅读笔记 - Context

Context作为golang中用于上下文控制的载体,其应用场景非常普遍,尤其在web开发中,Context更是随处可见。鉴于之前没有深入理解Context的实现原理,以及最近困惑于Context如何携带参数(Value),这篇笔记就来深入阅读下Context的源码,了解其原理ContextContext是接口类型,主要规范了四个方法type Context interface { // 1. Deadline() 返回该Context何时被取消 // 2. 当Context未设置截止时间时,o

2021-09-08 00:41:20 157

原创 redis-go源码阅读笔记

底层数据结构连接池pool// redis连接池type Pool struct { *pool.Slice // 核心是Slice结构体 c *Config // 连接池配置 type Config struct { *pool.Config // 包含连接池配置,下面有详解 Name string Proto string Addr string Auth string DialTimeo

2021-08-02 23:17:22 194

原创 redis连接耗尽问题排查

写在前面:这个笔记只是一个自我吐槽的帖子。。。没什么技术含量,如果不小心点进来,看到这就行了排查这个问题让我感触颇深,接触go已经快有半年时间了,但是很多知识点平时真的很难主动去接触,只有当问题来了,才会花时间在相关技术上探究;感觉这不是一个正常的技术积累过程,被动学习的技术提升很慢!但是如何主动学习呢?说实话,自己目前业余时间真不多,忙于业务,忙于出成果,可是这些成果好像很难对技术有较大提升(可能是业务方向决定的),技术人感觉太难了!是时候好好规划自己的时间和精力了!随便叨叨几句罢了。。。背

2021-07-27 00:38:58 1379

原创 Golang源码阅读笔记 - Channel

底层数据结构type hchan struct { qcount uint // channel以后数据大小 dataqsiz uint // channel大小 buf unsafe.Pointer // 有缓存的channel,其buf地址 elemsize uint16 closed uint32 elemtype *_type // channel中元素类型 sendx uint // 发送队列索引 recvx uint // 接收队列索引

2021-07-26 00:29:12 138

原创 计算机: 为什么int8是-128-127

背景这是一篇拖延了很久的博文,在TODO LIST里躺尸很久,已经忘记当时为什么要去了解这个了。。。只记得,以前一直想当然以为:“int8嘛,8位有符号整型,第一位是符号位,0表示正数,1表示负数,剩下7位存储数值。。。等等,那应该是-127 - +127啊,而且好像没有两个0(+0 和 -0)???”不过既然当时有需求,应该是真的用到了才对,学习一下不会错!原码、反码、补码我们使用+5, -5两个数,来说明原码、反码、补码原码: 即符号加上数值的绝对值(这里真值表示数的真实值,与之对应的机器数

2021-07-04 11:29:50 850

原创 Golang源码阅读笔记 - Sync.Map

sync.Map 底层数据结构// sync.map底层数据结构type Map struct { mu Mutex read atomic.Value dirty map[interface{}]*entry misses int}// read数据结构type readOnly struct { m map[interface{}]*entry amended bool // true if the dirty map contains some key not in

2021-07-03 19:27:46 228

原创 MySQL集群迁移方案

背景最近业务主库由于磁盘存储不够,需要对MySQL进行扩容;其实扩容的主要工作都在DBA侧,业务侧更多是配合DBA确定业务是否稳定,以及进行服务重启;这篇笔记,一是学习MySQL的平滑迁移方案,二是,从MySQL的迁移中,学习的对业务开发中的一些小小建议MySQL迁移中存在的问题我们业务生产环境是通过域名方式连接MySQL集群,使用“一主三从”的集群架构,读写分离通过业务侧自己使用不同域名区分;整个集群迁移方案,分为以下几步:新集群节点创建新节点加入集群,作为slave,同步老集群master

2021-06-27 23:32:20 819

“知行:技术人的管理之路” - 学习笔记

“知行:技术人的管理之路” - 学习笔记

2022-07-30

空空如也

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

TA关注的人

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