K8s的设计理念与架构
K8s的设计理念与架构设计理念Kubernetes 项目的理论基础则要比工程实践走得靠前得多,这当然要归功于 Google 公司在 2015 年 4 月发布的 Borg 论文了。Borg 系统,一直以来都被誉为 Google 公司内部最强大的“秘密武器”。虽然略显夸张,但这个说法倒不算是吹牛。因为,相比于 Spanner、BigTable 等相对上层的项目,Borg 要承担的责任,是承载 Google 公司整个基础设施的核心依赖。在 Google 公司已经公开发表的基础设施体系论文中,Borg 项目当仁不让地位居整个基础设施技术栈的最底层。
Kubernetes 项目在 Borg 体系的指导下,体现出了一种独有的“先进性”与“完备性”,而这些特质才是一个基础设施领域开源项目赖以生存的核心价值。
为了更好地理解这两种特质,我们不妨从 Kubernetes 的顶层设计说起。
首先,Kubernetes 项目要解决的问题是什么?编排?调度?容器云?还是集群管理?实际上,这个问题到目前为止都没有固定的答案。因为在不同的发展阶段,Kubernetes 需要着重解决的问题是不同的。但是,对于大多数 ...
Go 语言玩转Redis (二):数据结构与应用--字符串
Go 语言玩转Redis (二):数据结构与应用–字符串
第二到十一章节介绍Redis的数据结构与用法,包括上节说的字符串、散列、列表、集合、有序集合、HyperLogLog、位图、流、地理坐标等,我都会介绍其本身的基本命令及如何通过Go语言来调用。在详细介绍完后,我会带入一些使用场景并使用Go语言来实现,帮助大家和我更好的理解该数据结构。
其中Go语言的部分都会对应我github的链接,Go语言客户端的建立在(一)中有解释。
字符串字符串(string)键是Redis最基本的键值对类型,这种类型的键值对会在数据库中把单独的一个键和单独的一个值关联起来,被关联的键和值既可以是普通的文字数据,也可以是图片、视频、音频、压缩文件等更为复杂的二进制数据。
Redis为字符串键提供了一系列操作命令,通过使用这些命令可以:
为字符串键设置值。
获取字符串键的值。
在获取旧值的同时为字符串键设置新值。
同时为多个字符串键设置值,或者同时获取多个字符串键的值。
获取字符串值的长度。
获取字符串值指定索引范围内的内容,或者对字符串值指定索引范围内的内容进行修改。
将一些内容追加到字符串 ...
Go语言玩转Redis (一):聊聊 Redis 的学习体系
Go语言玩转Redis (一):聊聊 Redis 的学习体系
Redis 是一个开源内存数据结构存储器,经常用作数据库、缓存以及消息代理等。为什么要写一个Go使用的Redis的专题呢?因为Redis 我们平时经常用,但很多时候使用姿势不对,或是突然忘记某种场景该如何使用Redis实现。当需要程序快速响应的时候使用Redis做数据存储获取是不二的选择,这个专题就是想记录下Redis的框架体系,使用方式,场景,正确使用姿势等,便于之后的查询及逻辑构建
这个专题主要是基于 黄建宏老师的 《Redis 使用手册》一书,基于该书的讲解框架,结合Go语言的调用代码实例,及我自己的一些使用场景积累及说明写下。
Redis 的学习框架及特色
学习框架数据结构与应用Redis核心的9种数据结构,列举了操作这些数据结构的众多命令及其详细信息,融合 Golang 调用 Redis命令构建应用示例。通过这些示例,进行场景经验的积累。
附加功能Redis在数据结构的基础上为用户提供的额外功能,包括管理数据结构的数据库管理功能和自动过期功能,将数据结构持久化至硬盘从而避免数据丢失的持久化功能,提高多条命令执行效 ...
Go 流水线设计模式
Go 流水线设计模式
该文章为微信公众号 微服务实践 中的一篇文章,作者主要对 java 的流式处理进行了 Go 语言的实现及解释,流式处理可以说是模仿了工厂的流水线,数据抽象成原料,将不同的数据处理抽象成了流水线上的每一个操作。Rob Pike 在讲解 Go 语言为什么要引入语言级别的并发控制时说唯有引入并发才能描述现实世界上的种种行为。当时我就大受启发,发现代码确实是现实生活一种抽象。这篇文章可以说是对流水线行为的代码实现了。作者对于 Go 语言的数据流处理,功能架构等的理解都非常透彻,我把这篇文章收录进来希望对大家有帮助。
什么是流处理如果有 java 使用经验的同学一定会对 java8 的 Stream 赞不绝口,极大的提高了们对于集合类型数据的处理能力。
1234int sum = widgets.stream() .filter(w -> w.getColor() == RED) .mapToInt(w -> w.getWeight()) .sum();
Stream 能让我们支持 ...
算法专栏 (五):链表(下)
算法专栏 (五):链表(下)Go 语言实现链表的技巧链表的定义是不是很好去理解?但写起来很费劲。这篇文章就结合Go语言和你探讨一下如何写好链表代码,最后用一道经典的链表反转代码来收尾。
写好链表代码需要一些方法和技巧。我根据自己的学习经历和工作经验,总结了几个写链表代码技巧。
技巧一:理解指针或引用的含义事实上,看懂链表的结构并不是很难,但是一旦把它和指针混在一起,就很容易让人摸不着头脑。所以,要想写对链表代码,首先就要理解好指针。
我们知道,有些语言有“指针”的概念,比如 Go 语言;有些语言没有指针,取而代之的是“引用”,比如 Java、Python。不管是“指针”还是“引用”,实际上,它们的意思都是一样的,都是存储所指对象的内存地址。
接下来,我会拿 Go 语言中的“指针”来讲解,如果你用的是 Java 或者其他没有指针的语言也没关系,你把它理解成“引用”就可以了。
实际上,对于指针的理解,你只需要记住下面这句话就可以了:
将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变量的内存地址,指向了这个变量,通过指针就能找到这个变量。
这句话听 ...
算法专栏 (四):链表(上)
算法专栏 (四):链表(上)链表有啥用?为啥要学它,数组不够吗?首先要提起兴趣就要知道链表的应用场景,LRU 缓存淘汰算法就是经典的链表(Linked list)应用场景。
缓存是一种提高数据读取性能的技术,在硬件设计、软件开发中都有着非常广泛的应用,比如常见的 CPU 缓存、数据库缓存、浏览器缓存等等。缓存的大小有限,当缓存被用满时,哪些数据应该被清理出去,哪些数据应该被保留?这就需要缓存淘汰策略来决定。常见的策略有三种:先进先出策略 FIFO(First In,First Out)、最少使用策略 LFU(Least Frequently Used)、最近最少使用策略 LRU(Least Recently Used)。
如何用链表来实现LRU我放在最后。
链表结构相比数组,链表是一种稍微复杂一点的数据结构。对于初学者来说,掌握起来也要比数组稍难一些。这两个非常基础、非常常用的数据结构,我们常常将会放到一块儿来比较。所以我们先来看,这两者有什么区别。
我们先从底层的存储结构上来看一看。
为了直观地对比,我画了一张图。从图中我们看到,数组需要一块连续的内存空间来存储,对内存的要求比较高。 ...
算法专栏 (三):数组
算法专栏 (三):数组在每一种编程语言中,基本都会有数组这种数据类型。不过,它不仅仅是一种编程语言中的数据类型,还是一种最基础的数据结构。尽管数组看起来非常基础、简单,但是我估计很多人都并没有理解这个基础数据结构的精髓。
定义及如何实现随机访问?数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。
这个定义里有几个关键词:
第一是线性表(Linear List)。顾名思义,线性表就是数据排成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。其实除了数组,链表、队列、栈等也是线性表结构。
而与它相对立的概念是非线性表,比如二叉树、堆、图等。之所以叫非线性,是因为,在非线性表中,数据之间并不是简单的前后关系。
第二个是连续的内存空间和相同类型的数据。正是因为这两个限制,它才有了一个堪称“杀手锏”的特性:“随机访问”。但有利就有弊,这两个限制也让数组的很多操作变得非常低效,比如要想在数组中删除、插入一个数据,为了保证连续性,就需要做大量的数据搬移工作。
说到数据的访问,那你知道数组是如何实现根据下标随机访问数组元素的吗?
我们拿一个长 ...
算法专栏 (二):算法复杂度
算法专栏 (二):算法复杂度
数据结构和算法本身解决的是“快”和“省”的问题,即如何让代码运行得更快,如何让代码更省存储空间。所以,执行效率是算法一个非常重要的考量指标。
为什么需要复杂度分析?你可能会有些疑惑,我把代码跑一遍,通过统计、监控,就能得到算法执行的时间和占用的内存大小。为什么还要做时间、空间复杂度分析呢?这种分析方法能比我实实在在跑一遍得到的数据更准确吗?
首先,我可以肯定地说,你这种评估算法执行效率的方法是正确的。很多数据结构和算法书籍还给这种方法起了一个名字,叫事后统计法。但是,这种统计方法有非常大的局限性。
测试结果非常依赖测试环境测试环境中硬件的不同会对测试结果有很大的影响。比如,我们拿同样一段代码,分别用 Intel Core i9 处理器和 Intel Core i3 处理器来运行,不用说,i9 处理器要比 i3 处理器执行的速度快很多。还有,比如原本在这台机器上 a 代码执行的速度比 b 代码要快,等我们换到另一台机器上时,可能会有截然相反的结果。
测试结果受数据规模的影响很大后面我们会讲排序算法,我们先拿它举个例子。对同一个排序算法,待排序数据的有序度不 ...
算法专栏 (一):构建自己的算法体系
算法专栏 (一):构建自己的算法体系
为什么要写这个算法专栏的文章呢? 因为自己一直在断断续续的学习算法但发现一旦在很忙时放下了一段时间,很多知识点就会遗忘,我本来天真的以为如果完全理解就会完全掌握甚至融汇贯通,现在看来是自己 too young 了。
所有的知识都需要构建自己的体系这样才能记得牢固。所以这个专栏就是通过一些市面上我认为不错的算法资料进行自己的算法体系构建及知识记录。这个专栏是基于 极客时间中 王争老师 的《算法与数据结构之美》写下的,其中我把代码的用例都换成了Go语言,以及添加了Go语言对应数据机构算法的一些说明,还有Go语言对应算法的习题讲解
体系什么是体系体系就是在规定范围内,不同单位个体依照某种规律或秩序联系在一起的整体,是不同却又在某范围内的独立个体因为他们之间的联系而组成的一个系统。
为什么要建立体系其实从小到大我们总会发现有些人就是神一般的存在着,让我们感觉无法超越,他们知识广博且又深入。以前我觉得是天赋,但在我认为不是。他们是有一套建立知识体系的学习方法。当你建立起了某个知识的自己的体系的时候这个知识就很难忘记了。为什么?因为类型相似的知识之间建立起了 ...
如何处理一组并发任务
如何处理一组并发任务
这片文章是承接上一篇 聊聊 ErrorGroup 的用法和拓展 ErrorGroup 官方包的创建初衷就是给我们提供一个正确的处理一组任务的并发方式,经过拓展,我们还可以控制最大并发任务量,之后进一步拓展 Group 的用法更加多样,适用业务也更加多元,所以我这片文章题目就扩大到了处理一组并发任务。本文将从多个 Group 的多元拓展包入手,对并发处理任务的要点及实际处理方式进行总结和提炼,力求看后可以掌握处理并发任务的核心要点。
Facebook 拓展:facebookgo/errgroup这个 face book 的拓展包实际是对 waitgroup 的拓展,这个包不但可以用来记录并发控制并发协程的生命周期,还可以对所有并发任务的错误进行处理及记录。
Group 结构12345678// Group is similar to a sync.WaitGroup, but allows for collecting errors.// The collected errors are never reset, so unlike a sync.WaitGrou ...