Giter Club home page Giter Club logo

blog's People

Stargazers

 avatar  avatar

blog's Issues

徒手搭建kubernetes的教训 对于新领域,把概念拆分到自己熟悉&可以掌握的粒度

#k8s手动搭建步骤拆解

过程中发现要完善的工具

  • ssh用本机的vimrc

教训

急急急,搞大跃进呢你?这么急匆匆的搭完,就算一万个侥幸能用又咋样呢,遇到问题还不是抓瞎。本来就是一套技术栈。拆解到单元再反向学习逆推。
知识点

  1. 本机虚拟子网环境部署 完成80%,还差nat和static ip共存
  2. ca证书签证流程以及用法 OK
  3. systemd的配置文件写法,开机启动配置等
  4. 内网dns搭建和使用
  5. etcd 使用 单节点,多节点,静态发现,dns部署,不加证书,加证书,看文档!
  6. flannel ,配置docker跨主机通信
  7. k8s各个组件的作用
  8. kubeconfig的由来
  9. kubectl的token

k8s的部署过程拆解

  1. 环境配置:
    1. 如果能有多ip不同主机自然是好的。但是鉴于穷所以没有。笑
    2. 既然没有实际的计算资源,那就在本机自己来吧。
    3. 系统选用 archlinux 。 1master2slave。
    4. 以下是正式的步骤拆解 ===========
      • 安装系统,设置磁盘,设置网络。静态IP,nat共存
      • Scp存进必要的二进制安装文件
      • 配置好 Docker 使用 Flannel 跨主机通讯
      • dnsmasq 搭建
      • etcd 文档阅读,单节点多节点 静态发现 dns发现
  2. 证书生成
    • etcd
    • kube
  3. Systemd 启动服务的配置文件
    • Etcd
    • Kube-apiserver
    • Kube-schduler
    • Kubelet
    • Kube-proxy
  4. 安装启动
  • etcd
  • flannel
  • kube master
  • kube slave

Go标准库阅读计划一 Perm(洗牌算法)

func Perm(r *rand.Rand, n int) []int {
    m := make([]int, n)
    for i := 0; i < n; i++ {
        j := r.Intn(i + 1)
        fmt.Println("I:",i,"j:",j)
        m[i] = m[j]
        m[j] = i
   }
   return m
}

算法语言表述: 把当前列某一节点Y的值取给新加入节点X,然后维护一个0~N的递增队列,从这个递增队列里取一个最大的N赋给Y的值。

关于高并发的思考

关于高并发的思考

[TOC]

1. 序言&文章思路

构建高并发的流程: 单节点单线程(顺序执行) -> 单节点多线程并发(系统级并发) -> 分布式(多节点并发)
所以关于如何做到分布式高并发的思考。也要先明白单节点的缺陷。针对这些缺陷,分布式做出的应对措施,以及又带来了哪些问题。
从起源到巅峰。跟随前人思考和技术发展的脉络。这样的学习曲线比起直接关注最发达的时候要容易很多。这种做法的唯一难点就是如何去掌握发展脉络。
有测试数据&应用场景才真的叫作高并发。不同的情况,不同的复杂度下,对于高并发的并发数的要求都是不同的,所以这里只是思考一些影响并发数的因素。并不是一篇讲述如何做到高并发的记录。
回到正题。单节点的限制在哪里?
一次请求的接受到返回
尽可能的使用所有机器资源进行处理

2. 单节点单进程(一个主线程)

优点:

  1. 顺序程序,编码时不用考虑操作原子性,死锁等共享变量并发的难题。更加的快速

缺点:

  1. 遇到IO操作就会被挂起,直到IO完成后被调度唤醒。执行效率低
  2. 一次只能响应一个请求(致命缺陷)正是因为这个缺陷,导致了多任务操作系统的出现

3. 单节点多进程并发

优点:

  1. 并发执行,在多核的时代充分利用资源。
  2. 多核心线程,能防止被内核因IO阻塞而挂起

缺点:

  1. 对程序员的心智负担大,容易写出难维护,自己都不理解的代码。
  2. 开发的效率降低。
  3. 出BUG难调试

单节点的性能瓶颈:

  1. 磁盘io
  2. 网络带宽
  3. cpu算力
  4. 内存

能够依靠程序员提升效率

  1. 不死锁,减少bug
  2. 代码效率,线程有效执行,不等待。(用户级线程注意切换)

需要的观念:
明确cpu指令的时间级别、缓存读写一次、内存读写一次和磁盘读写一次的时间差。从这个时间差的比较里可以得到,缓存未命中和命中的差别。要能明确说出每条语句的执行时间级别!
只有有这样的意思之后,在执行一个长耗时操作等待的时候,能有意识的去增加一些短耗时任务,有效利用算力,比如会IO阻塞的语句开个goroutine去执行其他的任务。

分布式系统

分布式要明白的吧。还是时间级, n层架构彼此通信到最后完成一条请求的时间级
在这个基础上才说得上去优化。
在量级的前提下。
低量级一定是单机更效率
但是如果在量级提高的情况下。单机无法承担。所以在一个用户感知这个极限时间(或者业务要求时间内)的硬性要求时间之下都是为了支撑量级牺牲的时间。

思维发散

有个很有趣的问题。
万兆带宽连接下,a请求b无磁盘io,b读写数据库。 这样作为模式A
然后b单机读写数据库这样作为模式B。
这两种模式差别的时间有多少?
其实就是在不读写磁盘的前提下,网卡+内存的转发耗时多少的问题了。

网关的转发,这样的反向代理。是否保持和客户端的长连接?socket不关闭的前提下,在得到了转发服务器返回的时候就可以直接写入了。其实也只有这样吧。如果关闭socket的话是没办法重新连接的。要分清tcp和http的层级。

那这样的话网关能够同时保持多少个socket连接就很关键了,就是因为这样才会有事件机制和epoll。这样可以减少打开的线程数量。节约内核tcb结构体空间。还有socket套接字一定也是占用内存空间的。哪怕像goroutine这样8k内存。一百万个gorutine也要占用8g的内存了。千万呢?而且要清楚,http1.1的情况下,单个客户端是可以发起多个请求的。哪怕每个客户端10个请求那其实也只能够支持到个位数万的层次所以http2才必须长连接吧。而且这些都只计算了goroutine的内存呢!运行时,切换保存的上下文。都没有进行计算!所以甚至都没办法服务到万的用户,

所以网关也要分地区。dns来根据地区返回不同的网关?http不管再怎么转发也还是依赖于tcp的依次连接。也就是dns来进行网关的分流。这样就不用保持长连接了。CDN?内容分发?这个只能做到静态文件的分发,动态内容还是吃瘪但是可以有效的减少对静态资源的长连接数量。
反向代理。
可以一点一点实验,比如 实现一个http转发 看是不是保持着这个tcp连接直到内容服务器返回的时候返回结果。这大概基本就是了。因为这样才叫反向代理。服务器以为自己只是在接受网关的服务!
先查这些具体的时间等级和内存消耗

还可以写服务,然后按照这个一点一点的升级,每根据一点提升一次都记录一次性能。做个对比。这一套玩下来也就成为一个合格的程序员了吧!嘿。
做到这个再去试试编译原理,数据库确实兴趣没有很大。我还是对内存级别的更感兴趣好像
以上都是基于linux内核
然后这里缺的就是操作系统以及往下的了
比如如何让内核调度更有效率,更省内存
内核级别

在往下,我不做冯诺依曼体系结构啦哈哈哈哈

甚至通信行业的通信速度。网络硬件。

goroutine是基于内核线程。所以才可以分布在不同的cpu核心里跑。内核调度的原子层面就是内核线程

并发编程的一些概念(学习中)

线程安全的意思,应该是,任意一个方法都是原子的。不会因为线程被系统挂起或者切换导致的 数据错误,比如读出计算没来的急写入就被挂起了。后续的继续读写这块内存。关键是原子性

GO io/net包的接口-结构体 逻辑设计探究

三句话总结:
io包,io.Reader/Writer是对一切需要进行输入输出虚拟概念的抽象,例如: socket, file, device, buffer , connection, custom struct等概念。
net包, net.Conn是一切虚拟connection的抽象, 例如:IPConn,TCPConn, UDPConn,UnixConn等虚拟链接 。
包只提供作为抽象依据的 逻辑操作。

最近用的比较多的是net和io包,但是陷入net包繁杂的调用和零零散散的接口和结构体的逻辑里。无法提高到设计层面上形成一个系统性的认知,所以才有了这篇文章,这篇文章是我提高自己视角的过程。

io包里对于循环读一个可读结构的实现如下:

func ReadFull(r Reader, buf []byte) (n int, err error) {
  	return ReadAtLeast(r, buf, len(buf))
  }
// 这是io.ReadAtLeast的代码
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) {
   305  	if len(buf) < min {
   306  		return 0, ErrShortBuffer
   307  	}
   308  	for n < min && err == nil {
   309  		var nn int
   310  		nn, err = r.Read(buf[n:])
   311  		n += nn
   312  	}
   313  	if n >= min {
   314  		err = nil
   315  	} else if n > 0 && err == EOF {
   316  		err = ErrUnexpectedEOF
   317  	}
   318  	return
   319  }

为什么需要循环读?
因为buffer大概率情况下是没办法对应到数据的大小的。无法保证一次读取预期的所有数据的,所以需要循环读到结尾。
因为上面的场景非常的普遍出现,所以io包里有一个ReadFull函数实现。
那么无论是任何结构,只要是可以被读取的结构,都需要这个循环读的步骤。这个步骤又如何进行通用化呢?这里可是有各种各样的输入输出的虚拟概念需要进行read,上面代码里r.Read这个调用,可以通过r Reader这个接口进行储存这些抽象的概念。
有一个很关键的认知,如果你再读代码读到一个接口,你不明白到底做了什么实现的时候,那说明这个接口的设计上出现了问题,需要对接口的方法进行注释&重命名&拆分。也就是说,接口的方法一定是你能够明白这是在做什么!读起来能做到逻辑上是通顺的。 做到逻辑和真实数据结构的彻底分离。
说完了接口的一个使用案例,再来说一下接口之下的东西。
在这里先跳转到net包来看,Reader还是一个非常底层的动作,但是一个Conn是一个形容一类概念的动作组了。这个能看的比较明显一些。
首先,net.Conn
因为接口是静态语言的动态性的体现,所以一个Conn接口,可以在runtime时实际上是各种结构体。例如,IPConn,UDPConn, TCPConn等等。这些都是具体的结构体。他们是不同协议的连接,但是都是Connection。
image
大致能看一下golang里都有哪些Conn,有非常的多,而且这些Conn里既有interface,还有struct。
net.PackageConn interface implement by icmp.PackageConn,ipv4.PackageConn struct
syscall.RawConn interface implement by ipv4.RawConn struct
开始的时候真的非常让我困惑。直到想明白了。interface是为了在逻辑上通顺算法所使用的容器。而go则在命名上体现了这一点。
Conn 在进行代码书写的时候,逻辑上符合Conn的结构体都会进行伸缩式命名。例如IPConn, UDPConn, TCPConn
当然也有一些同名的interface与struct。例如net,icmp,ipv4包的PackageConn。这些命名相同的接口和结构体在阅读源代码的时候会带来更多的困惑。如果不提前知道这些问题的话。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.