MySQL 学习汇总

学习总结自《MySQL实战45讲》和 MySQL 官方文档

InnoDB 架构图


Read more...

2020-08-30

关于浮点数的运算,彻底弄懂为何 101.4 - 80.0 != 21.4

关于浮点数运算精度问题网上已有很多资料解释,但笔者还是想再造下“轮子”,加深理解。

先看一段简单的代码:

package main

func main() {
	var a float32 = 101.4
	var b float32 = 80.0
	var c float32 = 21.4
	var d float32 = 21.4
	if a-b == c {
		println("a-b = c")
	}
	if c == d {
		println("c = d")
	}
}

上述代码的运行结果为:

c = d

为何 a-b != c ? 如果我们直接在纸上用笔算,或者直接脑算都能得出 101.4 - 80.0 = 21.4。那么为何计算机算错了呢?

一句话说明原因:计算机在存储浮点数时存在精度误差。


Read more...

2020-08-18

Kubernetes 网络中数据包的流转

本文基于 kubernetes 1.17.4 + calico IPIP 模式 + kube-proxy IPtables 模式,观测 pod 间数据包的流动。

同宿主上 Pod 之间的流量

在 busybox-7d4f45df67-w2mvj 中,访问 nginx-7944498f44-7cllz。

首先查看 Pod 的路由表:

default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link

busybox-7d4f45df67-w2mvj 发送给 nginx-7944498f44-7cllz 的数据包会通过 eth0 发送给网关 169.254.1.1。

但网关 169.254.1.1 并不是实际存在的,calico 通过在宿主机上的 Veth Pair 上设置 proxy_arp,代理了 169.254.1.1 的 arp 请求,这样容器发送出去的所有数据包都会送到宿主机上的 Veth Pair。

calico 对于 169.254.1.1 的相关解释:

查看 busybox-7d4f45df67-w2mvj 在宿主机上的 Veth Pair:

➜  ~ calicoctl get workloadendpoint  yangxikun-k8s-busybox--7d4f45df67--w2mvj-eth0 -o yaml
apiVersion: projectcalico.org/v3
kind: WorkloadEndpoint
metadata:
  creationTimestamp: 2020-06-21T09:05:55Z
  generateName: busybox-7d4f45df67-
  labels:
    app: busybox
    pod-template-hash: 7d4f45df67
    projectcalico.org/namespace: default
    projectcalico.org/orchestrator: k8s
    projectcalico.org/serviceaccount: default
  name: yangxikun-k8s-busybox--7d4f45df67--w2mvj-eth0
  namespace: default
  resourceVersion: "1966670"
  uid: e56e7d6f-cab2-4b2a-96a5-1c8f908e567b
spec:
  endpoint: eth0
  interfaceName: cali84b7d149337
  ipNetworks:
  - 10.200.77.220/32
  node: yangxikun
  orchestrator: k8s
  pod: busybox-7d4f45df67-w2mvj
  profiles:
  - kns.default
  - ksa.default.default

从以上信息中可以知道 busybox-7d4f45df67-w2mvj 在宿主机上的 Veth Pair 为 cali84b7d149337,查看其 proxy_arp 的设置:

➜  ~ cat /proc/sys/net/ipv4/conf/cali84b7d149337/proxy_arp
1

现在数据包出现在了宿主机上,在宿主机上观察请求数据包和响应数据包的流动。


Read more...

2020-06-21

iptables 学习总结

参考文章:朱双印 iptables

防火墙概念

逻辑分类:

  • 主机防火墙:对单个主机进行防护
  • 网络防火墙:通常处于网络的入口/出口,服务于其背后的局域网

物理分类:

  • 硬件防火墙:在硬件级别实现部分防火墙功能,另一部分功能基于软件实现,性能高,成本高
  • 软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能低,成本低

iptables 概念

iptables 是一个客户端程序,与内核空间的 netfilter 交互。

netfilter 是集成到 linux 内核协议栈中的一套防火墙系统,用户可通过运行在用户空间的 iptables 来把相关配置下发给 netfilter。

netfilter 分为多个模块,各个模块的用户空间配置工具为:

  • 链路层:ebtables
  • 网络层ipv4:iptables
  • 网络层 ipv6:ip6tables
  • 专门用于 ARP 协议:arptables

wikipedia 关于 netfilter 中数据包的流图:

网络层部分的流图:


Read more...

2020-06-20

Kubernetes Scheduler

schedulerCache:Pod 与 Node 的缓存

type schedulerCache struct {
	stop   <-chan struct{}
	ttl    time.Duration
	period time.Duration

	// This mutex guards all fields within this cache struct.
	mu sync.RWMutex
	// a set of assumed pod keys.
	// The key could further be used to get an entry in podStates.
	assumedPods map[string]bool
	// a map from pod key to podState.
	podStates map[string]*podState
	nodes     map[string]*nodeInfoListItem
	// headNode points to the most recently updated NodeInfo in "nodes". It is the
	// head of the linked list.
	headNode *nodeInfoListItem
	nodeTree *nodeTree
	// A map from image name to its imageState.
	imageStates map[string]*imageState
}
  • nodes:维护节点名称到节点信息的映射
  • headNode:按照更新时间由大到小排序节点信息
  • nodeTree:维护 zone 和 node 关系
    • 一个 node 只属于一个 zone
    • 一个 zone 可以包含多个 node
  • imageStates:维护镜像名称到节点的关系

  • podStates:
    • pod:Pod 的最新状态
    • deadline:在结束绑定之后,等待多久没有从 apiserver 接收到绑定完成的事件,就会由 cache.cleanupExpiredAssumedPods 从缓存中删除
    • bindingFinished:是否已经完成绑定
  • assumedPods:值为 true 说明调度器为 Pod 分配了一个 Node

Pod 的调度状态变化:UnScheduled Pod -> (assume) -> Assumed Pod -> (bind) -> Scheduled Pod。


Read more...

2020-03-28

Kubernetes API 资源对象的删除和 GarbageCollector Controller

参考文档:

Kubernetes API 资源对象的删除方式

Foreground cascading deletion

显示级联删除,根对象首先进入 deletion in progress 状态。在 deletion in progress 状态会有如下的情况:

  • 对象仍然可以通过 REST API 可见。
  • 会设置对象的 ObjectMeta.DeletionTimestamp 字段。
  • 对象的 metadata.finalizers 字段包含了值 foregroundDeletion。

一旦对象被设置为 deletion in progress 状态,垃圾收集器在删除了所有 Blocking 状态的 dependents(ownerReference.blockOwnerDeletion=true)之后,对象才会被删除。

Background cascading deletion

隐式级联删除,kubernetes-apiserver 会立即删除对象,然后垃圾收集器会在后台删除 dependents。

Orphan

非级联删除,根对象首先进入 deletion in progress 状态。在 deletion in progress 状态会有如下的情况:

  • 对象仍然可以通过 REST API 可见。
  • 会设置对象的 deletionTimestamp 字段。
  • 对象的 metadata.finalizers 字段包含了值 orphan。

一旦对象被设置为 deletion in progress 状态,垃圾收集器在解除所有 dependents 的关联之后,对象才会被删除。

Gracefully terminate

针对 Pod 特有的删除方式,允许优雅地终止容器。先发送 TERM 信号,过了宽限期还未终止,则发送 KILL 信号。

kube-apiserver 先设置 ObjectMeta.DeletionGracePeriodSeconds,默认为 30s,再由 kubelet 发送删除请求,请求参数中 DeleteOptions.GracePeriodSeconds = 0,kube-apiserver 判断到 lastGraceful = *options.GracePeriodSeconds = 0,就直接删除对象了。


Read more...

2020-03-17

Kubernetes Informer 与 Lister 详解

简介

  • Informer:
    • 同步本地缓存,把 API 资源对象缓存一份到本地
    • 根据发生的事件类型,触发事先注册好的控制器回调
  • Lister:从本地缓存中获取 API 资源对象

Read more...

2020-03-05