开源工程
文章平均质量分 63
kdb_viewer
这个作者很懒,什么都没留下…
展开
-
chubby总结
目录架构文件名空间分布式锁缓存一致性chubby master故障恢复client和chubby master交互master故障恢复master选举流程chubby服务端架构paxos算法实现chubby是一个面向松耦合分布式系统的锁服务,是paxos算法的工程实现。架构如图,chubby锁服务有中心化节点,这里以5个实例组成的chubby集群为例,根据paxos算法选举唯一master,client通过lib向chubby master发送rpc请原创 2021-04-25 16:37:22 · 1012 阅读 · 0 评论 -
google bigtable 浅析
目录概述key-value模式详解构件组件tablet概念tablet组织结构tablet分配tablet变更tablet服务架构优化局部性群组缓存bloom filter概述bigtable是一个key-value模式的分布式结构化存储系统,不提供传统关系数据库的sql功能,设计目标是高适用性、高扩展性、高性能、高可用key-value模式详解bigtable的key-value模式如下:(row:string, column:str原创 2021-04-25 13:46:42 · 1375 阅读 · 0 评论 -
GFS(google file system)深度剖析
目录架构一致性模型系统交互快照master节点管理文件锁文件删除过期失效的副本检测高可用数据完整性架构gfs(google file system)包含一个master节点和若干个chunk server。master节点维护元数据,chunk server存储实际数据。访问gfs通过client进行,client通过lib的形式集成在用户程序中,先访问master节点获取要访问文件所在的chunk节点地址,然后访问chunk server操作数据。.原创 2021-04-24 23:47:24 · 1246 阅读 · 0 评论 -
bthread源码分析(十)进阶数据结构FileStatus
FileStatus在用户态维护一个文件描述符机制,设计这样一个数据结构有如下原因:epoll_ctl开销大,不宜多次调用 用户态butex同步机制,bthread可以基于butex的同步编程模式等待文件描述符源码地址:bthread/file_status_monitor.h bthread/file_status_monitor.cpp这里给出一个例子:如图,每个打开的fd在内存中维护一个对应的FileStatus对象,bthread1在fd3上butex_wait,bthread2原创 2021-04-20 17:27:06 · 185 阅读 · 0 评论 -
bthread源码分析(九)进阶数据结构 ExecutionQueue
ExecutionQueue是一个多生产者-单消费者模型的工作队列,特性:wait-free,基于butex同步 队列元素数量无边界 没有daemon thread存在,消费者线程自动启动、自动销毁。当有任务加入队列,启动一个bthread持续消费队列并执行任务,直到队列为空,销毁这个bthread 提供有序性和优先级管理,高优先级任务先于低优先级任务执行,相同优先级内部任务按照FIFO顺序执行。高优先级任务不是即时抢占的,即若当前正在执行低优先级任务,那么高优先级任务插入不会抢占低优先级任务立刻原创 2021-04-20 17:25:57 · 410 阅读 · 0 评论 -
bthread源码分析(八)进阶数据结构bthread_id:以id关联data的同步机制
bthread_id是一种同步机制,其思想是为需要同步的数据关联一个带版本管理的id,在这个id上做加锁、解锁等同步操作。bthread_id的同步操作在锁内进行,其效率比mutex低,也就是说bthread_id不能用做通用的同步机制,其适用于对一个对象进行一系列低冲突操作的场景,用于同步这些操作。源码位置 bthread_id.h bthread_id.cppid版本号管理 first_ver | * | * | ... | locked_ver -1| locked_ver | ..原创 2021-04-20 17:23:49 · 381 阅读 · 1 评论 -
bthread源码分析(七)bthread调度逻辑
TaskControl:全局一个,控制所有TaskGroup和工作线程,初始化时根据配置数量创建指定数量的工作线程。包含4个parkinglot供线程睡眠等待任务使用。非工作线程添加任务时通过TaskControl进行,在TaskControl中随机选择一个TaskGroup并将任务添加到该TaskGroup队列中TaskGroup:每个工作线程绑定一个TaskGroup,TaskGroup中包含工作队列等信息源码地址:bthread/task_control.h bthread/task_cont原创 2021-04-20 17:23:08 · 420 阅读 · 0 评论 -
bthread源码分析(六)bthread同步机制
Butexbutex是bthread使用的类futex的32bit同步原语,可用于bthreads或者pthreads的同步,不可用于同步多进程。源码地址:bthread/butex.h bthread/butex.cppButex数据结构如图,每个Butex内部包含一个32bit的用于同步的value和一个WaiterList。bthread进行同步操作时先判断Butex中的value是否和expect value相等,若是那么此bthread拿到了这个Butex,否则在栈上分配一个W原创 2021-04-20 17:21:45 · 643 阅读 · 0 评论 -
bthread源码分析(五)上下文和栈实现
Contextcontext是bthread的上下文,提供上下文初始化和上下文切换功能源码位置:bthread/context.h bthread/context.cpp接口api 1 2 3 4 5 6 7 8 9 10 11 12 13 // 上下文切换,从ofc切换到nfc intptr_t BTHREAD_CONTEXT_CALL_CONVENTION原创 2021-04-20 17:20:40 · 759 阅读 · 0 评论 -
bthread源码分析(四)定时器实现
bthread中启用一个pthread作为全局唯一的定时器处理线程,所有定时任务都通过这个pthread进行管理和调度。由于全局只有一个定时任务处理线程,因此定时任务中不能放耗时长的逻辑,否则会给后续任务造成延迟。源码位置:bthread/timer_thread.h bthread/timer_thread.cpp接口api 1 2 3 4 5 6 7 8 9 //调用者传入一个方法fn和方法的参数ar原创 2021-04-20 17:19:06 · 365 阅读 · 0 评论 -
bthread源码分析(三)基础数据结构和组件
1、WorkStealingQueueWorkStealingQueue是一种无锁队列,用做bthread中的任务队列。WorkStealingQueue提供三种操作:push,pop,steal。由于push和pop都是在本线程中完成的,因此push和pop操作不会并发,两个push和两个pop之间也不会并发,但是steal是从其他线程发起的,因此会和push或pop并发。源码位置:bthread/work_stealing_queue.h基本操作队列保存头尾指针_top和_bottom,原创 2021-04-20 17:18:22 · 471 阅读 · 0 评论 -
bthread源码分析(二)ObjectPool && ResourcePool
对象池存储固定大小的对象,针对多线程环境反复使用fixed size小对象的场景相比每次都new和delete有明显的性能提升。同时由于对象池不销毁对象的特性,极大简化了无锁编程中对象生命周期管理的问题。源码位置:base/resource_pool.h base/resource_pool_inl.h base/object_pool.h base/object_pool_inl.hbthread提供对象池ObjectPool和资源池ResourcePool,两者的差异仅仅在于ResourcePo原创 2021-04-20 17:16:33 · 364 阅读 · 0 评论 -
bthread源码分析(一)概述
bthread是一个M:N线程库,是brpc的核心组件。bthread实现了用户态上下文切换,主要有2个目标,一是降低编码难度,业务层可使用同步编程模式;二是在多核系统上取得更好的扩展性和局部性,提供更低的延时,更高的cpu利用率。bthread和协程谈到bthread,就不得不提协程。首先要强调的一点是,bthread不是协程。一般上我们说的协程的概念是M:1线程库,多个协程跑在一个底层pthread上,一个协程阻塞就会导致协程所在的pthread阻塞,进而该pthread上的其他协程都无法被调度原创 2021-04-20 17:15:01 · 1097 阅读 · 1 评论 -
leveldb源码分析(七)db操作流程详解
1、GetGet操作较简单,先查内存的两个memtable,查不到的话继续查磁盘文件,伪代码如下: Get(options, key, value) { mutex.lock() { sequence_num = options.has_snapshot() ? options.snapshot() : versions.last_sequence()// 获取seq num mem.Ref(), imm.R...原创 2021-04-19 15:58:31 · 405 阅读 · 0 评论 -
leveldb源码分析(六)Version
leveldb的db实现包含一组version,所有version在version_set中维护,最新的version为current。每个version记录一个db状态,包含每个level的文件、每个文件的key range等信息。version中维护一个ref计数以管理声明周期,保证old version在仍有迭代器访问时不会消失。所有version保存在一个version_set中。源码位置:db/version_set.h db/version_set.cc这里结合一个具体例子如图:原创 2021-04-19 15:57:38 · 320 阅读 · 0 评论 -
leveldb源码分析(五)Compaction
leveldb进行Compaction对文件进行合并和层级下沉,原因有如下几个:记录一经写入不会修改,对同一个key的多次操作会产生多条记录,占用了额外空间需要清理 合并倾向于把不活跃key沉降到下层level,上层level活跃度高,利用局部性原理减少IO开销leveldb会进行2种Compactionminor compaction将immutable memtable刷到磁盘。内存中的memtable有大小限制,一方面内存是有限的,另一方面过大的memtable会导致过大的LOG文件,原创 2021-04-19 15:56:32 · 311 阅读 · 0 评论 -
leveldb源码分析(四)cache
在前文的leveldb文件层次结构中,内存中只显示了memtable,然而内存中不只有memtable,实际上leveldb在内存中维持了sst文件内容的缓存。这里介绍leveldb的cache实现和两个使用场景。LRU实现leveldb提供了一个Least recently used的缓存实现,源码位置:include/leveldb/cache.h util/cache.cc如图,leveldb的LRU实现包含一个hash表和两个双链表,查找数据在hash表中进行,hash使用拉链法,n原创 2021-04-19 15:55:31 · 304 阅读 · 0 评论 -
leveldb源码分析(三)文件格式
levedb层级组织如图,leveldb由内存中的memtable和磁盘文件组成,memtable和ldb文件中均按key有序存储,level0的各文件管理的key空间可能有重合,从level1到level6,每个level内的文件key范围不会重合。下面分别介绍memtable和磁盘文件格式。memtable数据结构memtable使用skiplist维护插入的数据,不允许删除数据,插入数据按自定义的Comparator进行比较按序插入。memtable内部没有同步机制,由于不会删除.原创 2021-04-19 15:54:01 · 1034 阅读 · 0 评论 -
leveldb源码分析(二)leveldb数据结构
1、skiplist跳跃表是一种O(logN)插入和查找操作的数据结构,和红黑树类似,优点是实现简单,易于理解。levedb使用的跳跃表在一般跳跃表的基础上做了一些改造,特点如下:内部没有同步机制,写操作需要调用者同步,读操作可并发,写不阻塞读,读者可能丢失同时进行的写,但是不会读取不一致数据 相同的key只允许插入一次 不提供删除操作,数据插入后不允许修改内容 支持用户定制比较器用于key的比较skiplist内存管理skiplist使用arena管理内存,目的是缩减小内存的申请次数以原创 2021-04-19 15:48:49 · 796 阅读 · 0 评论 -
leveldb源码分析(一)概述
leveldb是key-value模式数据库,出自Jeff Dean和Sanjay Ghemawat之手,适用于顺序读写场景。各大厂均有以leveldb为积木搭建的成熟数据库产品,如google的bigtable,baidu的tera等,在工程实践上取得了广泛成功。leveldb以其良好的编程风格和设计理念为人称道,阅读leveldb源码对提升自己的编程能力大有裨益。leveldb源码地址https://github.com/google/leveldbleveldb源码目录结构 db原创 2021-04-19 15:46:19 · 909 阅读 · 0 评论 -
leveldb NoDestructor类解析
leveldb提供了byte级别的比较器,见util/comparator.cc,这个文件中提供的BytewiseComparator类对象通过无析构函数的单例提供,代码如下:const Comparator* BytewiseComparator() { static NoDestructor<BytewiseComparatorImpl> singleton; return singleton.get();}这里单例通过static语义实现,保证第一个到达此函数c原创 2020-09-08 17:05:03 · 763 阅读 · 2 评论 -
dhcpd开源工程(二) 常用的几个关于ip地址的结构体
1.in_addr,在inlcude/netinet.h中声明,用于存储ip地址,声明如下typedef uint32_t in_addr_t;struct in_addr { in_addr_t s_addr; };2.广播、环回、组播等地址,在include/netinet.h中声明,声明如下/* Address to accept any incoming message...原创 2018-05-25 14:58:04 · 308 阅读 · 0 评论 -
dhcpd开源工程(三) dhcpd启动脚本
脚本设计:脚本中必须包含个函数,start(),stop(),restart(),reload(),例如,键入service dhcpd start命令,会调用start函数,restart()和reload()很简单,stop函数中kill进程,并杀出pid文件,这里主要写start函数的设计思路,先检查是否有配置文件,若没有的话,直接退出并打印信息;检查指定路径是否有租约文件,若没有,创建;检...原创 2018-05-25 15:13:27 · 1202 阅读 · 1 评论 -
redis基础数据结构(一)可变长字符串sds
redis中的字符串是二进制安全的,传统C字符串以'\0'为结尾,只能用于保存纯文本,不能用于保存音频、视频等二进制文件,因为只要在中间遇到'\0'就被截断了。redis的sds模块所有api都使用二进制方式处理字符串,因此叫做字节数组更为贴切。数据结构:一个带控制结构的字符串,内存中起始地址是一个控制结构,包含一个柔性数组用来保存字符串,结尾加'\0',使用的时候返回的是字符串起始地址...原创 2018-06-12 20:33:20 · 787 阅读 · 0 评论 -
redis基础数据结构(二) 内存管理模块
redis可选内存管理方式为tcmalloc或jemalloc,用宏控制,一般用jemalloc性能最好,底层调用remalloc接口,redis的内存管理模块只是封装函数,内存管理在zmalloc.h和zmalloc.c中。zmalloc.c中定义一个全局变量used_memory和两个用于管理user_memory的宏,如下#define update_zmalloc_stat_alloc(_...原创 2018-06-12 23:58:52 · 276 阅读 · 0 评论 -
redis基础数据结构(四) 字典dict
字典是一种key和value建立一一对应关系的一种结构,redis中的字典用hash实现,代码在dict.h和dict.c中。dict.h中提供的结构和宏定义:typedef struct dictEntry { void *key; union { void *val; uint64_t u64; int64_t s64; ...原创 2018-06-20 18:46:44 · 319 阅读 · 0 评论 -
redis基础数据结构(三) 双链表adlist
源码在adlist.h和adlist.c中,是一个标准的双链表,结构如下typedef struct listNode { struct listNode *prev; struct listNode *next; void *value;} listNode;使用时和内核链表的思想是一样的,将listNode嵌入其他结构中。list是头,listnode是节点。list...原创 2018-06-13 10:26:52 · 198 阅读 · 0 评论 -
redis基础数据结构(六) 基数统计
基数统计即统计一个数据集中不重复元素的个数,一种显然的实现是使用不相交集,缺陷是随着数据增加内存占用线性增加,海量数据下不可用;一种更常见的方法是使用B-树,所有数据在叶子节点保存,叶子节点在磁盘中,上层节点在内存中,因此占用内存的问题得到解决,查找时间O(logN),但是读取磁盘开销太大;最完美的方法是使用bitmap,因为bit是最小存储空间,可以保证内存占用最小。以上都是准确基数排序的方法,...原创 2018-06-22 19:59:03 · 1490 阅读 · 0 评论 -
redis基础数据结构(七)整数集合
redis的整数集合在intset.h和intset.c中,intset.c中提供的api:_intsetValueEncoding:根据提供的value返回不同的编码方式,编码方式一共有3种,16,32,64_intsetGetEncoded:根据提供的编码方式,返回pos位置的值_intsetGet:返回编码方式,是_intsetGetEncoded的封装...原创 2018-06-23 10:57:50 · 212 阅读 · 0 评论 -
redis基础数据结构(八) 压缩列表
ziplist总体设计:<zlbytes> <zltail> <zllen> <entry> <entry> ... <entry> <zlend>所有字段都用小端存储zlbytes:一个uint32_t,保存一个ziplist总的内存字节数,包括自己,这个字段的意义是,需要resize的时候,不需要对ziplis原创 2018-07-03 11:35:52 · 361 阅读 · 0 评论 -
redis基础数据结构(五) 跳跃表
跳跃表是一种对顺序链表的改进,将查找顺序链表的O(N)时间优化为O(logN)时间,空间增加约两倍,有两种常见变体,一种是随机跳跃表,使用随机算法决定每个节点的高度,缺陷有产生随机数的开销;另一种是123确定性跳跃表,除了头和尾,第n层相邻的两个节点之间只有1个,2个或者3个第n-1层的节点,当插入或删除时调整结构;另一种对顺序链表的O(logN)优化是,使用一个指针数组,数组中每个指针指向一个链...原创 2018-06-20 17:30:20 · 580 阅读 · 1 评论 -
openldap (一) ldap连接
连接和初始化ldap相关api在open.c中提供:ldap_open_defconn:创建一个默认连接,调用者确保调用此函数时已经加锁ldap_open:初始化并连接到ldap服务器ldap_create:创建一个ldapldap_init:用主机名和端口号初始化ldap库ldap_initialize:用url初始化ldap库ldap_init_fd:初始化读写管道...原创 2018-07-23 15:12:35 · 1397 阅读 · 0 评论 -
redis缓存机制
redis提供了三种缓存机制,LFU,LRU,TTL1.LFU,least frequently used,即最小使用频率淘汰,每个对象使用共计24bit空间用来实施这个算法,24bit分成2个部分,前16bit用来记录上次减少时间(减少的是后面8bit计数器),后面8个bit是一个对数计数器,用来记录这个对象的访问次数。需要注意的是,这个字段不是一直增加的,也需要减少,否则会出现一个情况,一...原创 2018-08-06 11:34:53 · 16078 阅读 · 0 评论 -
redis基础数据结构(九) 快速列表
quicklist是一种双链表,每个节点是一个ziplist,quicklist.h中提供的结构定义如下:typedef struct quicklistNode { struct quicklistNode *prev; struct quicklistNode *next; unsigned char *zl; unsigned int sz; ...原创 2018-08-02 10:49:35 · 177 阅读 · 0 评论 -
c++ primer plus chapter16 string类和标准模板库
内容摘要:1.标准c++ string类2.模板auto_ptr,unique_ptr,shared_ptr3.标准模板库STL4.容器类5.迭代器6.函数对象functor7.STL算法8.模板intializer_listC语言提供的字符串相关函数在string.h和cstring中,而c++的string类是在头文件<string>中支持的,要...原创 2018-08-23 18:16:37 · 157 阅读 · 0 评论 -
C语言访问redis
redis采用源码或者二进制文件安装方式,启动服务,如下:ps aux | grep redisroot 4772 0.0 0.0 103184 856 pts/0 S+ 09:02 0:00 grep redisroot 20639 0.1 0.1 143908 7660 ? Ssl Aug08 37:57 /usr/lo...原创 2018-08-24 11:40:10 · 1606 阅读 · 0 评论 -
《数据算法 hadoop spark大数据处理技巧》笔记 前言
MapReduce:是一个软件框架,采用并行、分布式方式处理大数据集,目标是实现可伸缩性,重点是编写两个函数:map和reducemap():过滤和聚集数据。主节点得到数据,将数据分成小块,分布到若干从节点处理。从节点对每个数据块应用同样的转换函数,将结果传回主节点reduce():根据map()生成的键完成归约、分组、总结。主节点根据唯一的键-值对将接收到的结果进行洗牌、聚集,传回从节点...原创 2018-09-06 11:50:09 · 533 阅读 · 0 评论 -
dhcpd开源工程(一) 守护进程中选择dhcp 的udp_port
dhcpd传输层基于UDP协议,dhcpv4的client和server分别使用udp的68和67号端口,在守护进程中,关于port设置的代码结构如下:判断全局变量local_port,若是0,从getenv函数从环境中获取DHCPD_PORT环境变量的值,getenv函数原型如下:/* Return the value of envariable NAME, or NULL if it does...原创 2018-05-25 14:35:40 · 614 阅读 · 0 评论