🌓

存储——分布式存储底座

分布式存储底座包括分布式文件系统和分布式一致性KV存储。对外满足的条件 1. 提供数据可靠性,底座之上不需要担心数据损坏 2. 提供数据可用性,节点崩溃不影响数据读写 3. 集群级接口,多机节点可访问

阅读全文

编程语言(6)—编译、运行和调试

写完了代码第一件事是编译,编译失败只能根据编译器通知修改代码;编译通过了第二件事是跑UT,UT不过需要进行调试。调试包括debug和release包的调试,线上进程的运行问题有时候也需要调试,调试的主要方式是调试工具和日志(包括print大法)。为了发现问题,有时候还需要添加报警日志。

提高代码的健壮性,编译器、静态检查和格式化工具、调试、单元测试、日志等是开发必不可少的

阅读全文

编程语言(5)—文件IO和网络库

linux系统的文件接口是十分重要的抽象, 也就是“一切都是文件”。借助文件IO,用户程序可以读写磁盘设备、网络设备、甚至管道、内存等。

阅读全文

编程语言——静态变量和静态函数

简谈编程语言中的静态变量和函数

阅读全文

存储——缓存简谈

缓存存放的是临时数据,相比主存,缓存往往速度更快,容量更小。

缓存往往是多级的,由内而外,cpu cache -> 内存 -> ssd -> hdd(单机) -> 服务器/多节点/oss/nas等

缓存需要淘汰,因此缓存往往由链表组成,根据LRU算法淘汰

只要有缓存就会有一致性问题

阅读全文

系统——并发简谈

并发可分成并发对象和并发协调两部分。并发对象可以是进程、线程、协程、以及多机并发。并发协调包括锁(进程锁、线程锁、协程锁、分布式锁),信号,信号量,条件变量,通信队列等。

并发编程的三个特点是原子性、有序性、可见性原子性要求写操作要么执行完要么不执行,不能中途执行一半被干扰,并发编程中需要保证所有操作都是原子的;完全要求顺序的程序无法并发,因此并发编程的特点是原子性+部分有序。可见性是针对并发读共享变量,如果并发对象之间读共享变量,就要维护共享变量的可见性,一个并发对象修改另一个并发对象可以看到。(如果只有并发写,只要考虑原子性和顺序性,不需要可见性)

阅读全文

编程语言(4)—函数和并发编程

并发编程是提高程序处理能力的重要手段,也是编程语言必备的能力。并发的对象是函数,函数作为任务被多个并发计算对象执行。

并发的单位可以是进程、线程和协程(用户态线程),并发需要保证的三个特点:原子性、顺序性和可见性。

  1. 原子性表示操作要么全部成功,要么全部失败,执行中不能被中断。原子性通常使用锁(包括悲观锁、乐观锁)保证。
  2. 顺序性表示任务执行的顺序与任务提交时的顺序一致。顺序性通常使用队列(先进先出)保证,常见的是是生产者-消费队列保证顺序性,例如golang的channel。好的顺序设计,可以保证每个阶段只有少量线程执行,减少锁的使用。减少共享内存的使用,多用顺序性的信号通知,减少锁争抢。在分布式系统中,面对ABA问题,还会对操作和共享内存增加版本号来保证顺序性。
  3. 可见性表示对共享内存的修改对其他线程可见。常见的是使用内存屏障(memory barrier)保证可见性,内存屏障是CPU提供的一种同步机制,保证CPU执行到内存屏障之前的指令都执行完成,再执行内存屏障之后的指令。C++原子类的内存序就是在保证可见性。

阅读全文

编程语言(3)—数据结构和算法

数据结构(容器)库和算法库是最基础的库之一。字符串是人类语言的记录,是计算机处理的主要对象。

阅读全文

编程语言——映射结构

映射是最重要的数据结构之一,动态数组也可以看做特殊的映射。映射的优势是,它的增删改查性能都很好。增->增加key,删->删除key,改->更改某key的vakue,查->给定key查询value。

阅读全文

linux系统(3)——系统监控和问题排查

本文介绍linux系统的监控工具和问题排查的一般步骤,文章大体内容

  1. 用户程序一定要丰富trace和日志,并对trace做监控。正常情况下如果程序处理出现问题,会在监控告警中显示,介入排查可以通过trace和日志,判断出问题的文件、执行的线程等信息,绝大多数排查可以在这里停止,根本不用抓栈抓core。trace和日志必须包含的, 1. 时间戳 2. 函数名和位置 3. 线程ID和线程名, 这三个信息是排查必须
  2. 如果日志无法给出运行错误的原因,则需要进入机器查看。首先看有无core产生,产生core的原因一般是非法内存访问、double free、内存踩坏等或oom,因此首先去/var/log/messages 看是否oom导致,oom会记录到/var/log/messages日志。
  3. 如果没有core产生,但进程处理慢。可以先perf top -K -t $tid 查看耗时长的函数,原因大概是1. 被流控 2. 底层数据库/IO服务处理慢,反压上层 4. CPU/IO/网络被打满,资源不足 5. 线程数量不足,任务队列堆积 等原因,这些原因本都应该展示在监控和日志里
  4. 如果有oom,需要内存占用高的线程抓core,分析内存占用高和是否有内存泄漏;如果有core, 则需要分析产生core产生的原因。先在debug 环境下尝试复现core,同时调用valgrind等工具分析。分析core比较困难,可以直接找最有经验的人来协助。

阅读全文