GVKun编程网logo

Python 学习笔记 - 基础篇(python初学笔记)

2

本篇文章给大家谈谈Python学习笔记-基础篇,以及python初学笔记的知识点,同时本文还将给你拓展1.python基础篇---监控股票、Angular2Directive学习笔记-基础篇、Kube

本篇文章给大家谈谈Python 学习笔记 - 基础篇,以及python初学笔记的知识点,同时本文还将给你拓展1.python 基础篇 --- 监控股票、Angular2 Directive 学习笔记-基础篇、Kubernetes 学习笔记-基础篇、mysql 学习笔记--基础篇等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Python 学习笔记 - 基础篇(python初学笔记)

Python 学习笔记 - 基础篇(python初学笔记)

OSC 请你来轰趴啦!1028 苏州源创会,一起寻宝 AI 时代

安装

Linux

Linux 已经自带 Python 了,我的 Centos7 自带 Python2.7.4,我通过源码安装来更新版本。

#!/bin/bash
#源码安装
wget https://www.python.org/ftp/python/2.7.9/Python-2.7.9.tgz
tar -zxvf Python-2.7.9.tgz
cd Python-2.7.9

#编译安装
./configure
make
make install

安装 pip(推荐安装,非必需)

pip 是一个包管理器,安装后方便之后框架和依赖包的安装使用。推荐安装。

#!/bin/bash
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py

Hello World

>>> print ''hello, world''
hello, world
>>> exit()

编辑器

推荐 Vim,Windows 下使用 Notepad++。

hello_world.py

#!/usr/bin/env python
# -*- coding:utf8-*-

# 第一行用于在Linux下被识别从而直接运行
#第二行用于定义此文件的字符编码是utf8,防止乱码,这是一个好习惯

#print可以使用以下两种形式来输出字符到控制台,推荐第二种,可以兼容Python3
print ''Hello World''
print(''Hello World'')
#可以用逗号分隔每个字符串,打印出来遇到逗号会输出一个空格
print ''Hello'',''World''

#读取用户输入的字符并赋予name变量
name = raw_input()

运行

python hello_world.py

基础

  • #开头是注释
  • : 结尾是代码块,代码块缩进推荐四个空格

数据类型

数字

  • 整数: 例如 1 100,16 进制以 0x 开头,例如 0xff00
  • 浮点数: 例如 3.14,科学记数法把 10 用 e 替代,1.23x10 的 9 次方的就是 1.23e9 或者 12.3e8 注:整数运算永远精确,浮点数可能存在四舍五入

字符串

  • ''''"" 括起来的任意文本,转义使用 \,用于转义单引号、双引号和特殊字符(例如换行符)
  • r'''' 表示原始字符串,不需要转义
  • ''''''我是内容'''''' 这种三个引号(单双都行)扩起来表示可以换行的文本
  • r''''''我是内容'''''' 表示多行原始字符串,不需要转义
  • u'''' 表示 Unicode 字符串
  • 字符串格式化 ''Hello, % s'' % ''world''

布尔值

  • True
  • False 布尔值可以用 andornot 运算

空值

None

变量

变量的类型取决于第一次赋值的类型。

a = 1

常量

Python 中无常量,约定全部大写的变量为常量(值依旧可以变)。 PI = 3.14

### 类型判断和转换

a = ''123''
# 判断类型
type(a)
# 转换为int,其他类型同理
int(a)

## 转换函数表
int(x [,base ])                #将x转换为一个整数
long(x [,base ])             # 将x转换为一个长整数
float(x )                        #将x转换到一个浮点数
complex(real [,imag ])  #创建一个复数
str(x )                           #将对象 x 转换为字符串
repr(x )                        #将对象 x 转换为表达式字符串
eval(str )                      #用来计算在字符串中的有效Python表达式,并返回一个对象
tuple(s )                       #将序列 s 转换为一个元组
list(s )                           #将序列 s 转换为一个列表
chr(x )                          #将一个整数转换为一个字符
unichr(x )                     #将一个整数转换为Unicode字符
ord(x )                          #将一个字符转换为它的整数值
hex(x )                          #将一个整数转换为一个十六进制字符串
oct(x )                           #将一个整数转换为一个八进制字符串

序列

list(列表)

classmates = [''Michael'', ''Bob'', ''Tracy'']
#list中元素个数(得到3)
len(classmates)
#最小元素(得到''Bob'')
min(classmates)
#最大元素(得到''Tracy'')
max(classmates)
# 访问元素(得到''Michael'')
classmates[0]
# 倒数第一个元素(得到''Tracy'')
classmates[-1]
# 追加元素
classmates.append(''Adam'')
# 位置1插入元素,后面元素会依次后推 
classmates.insert(1, ''Jack'')
# 删除末尾元素
classmates.pop()
# 删除位置 1 的元素
classmates.pop(1)
del classmates[1]
# 删除片段
del classmates[i: j]
# 替换元素
classmates[1] = ''Sarah''
#切片(选取第一个到第二个元素组成新列表)
classmates[1: 2]
#切片(选取第一个到第三个元素组成新列表,每隔两个,按照原始list,得到''Bob'')
classmates[1: 3: 2]
# 不同类型元素
L = [''Apple'', 123, True]
# list嵌套(list做为list的一个元素)
s = [''python'', ''java'', [''asp'', ''php''], ''scheme'']
#取得''php''(相当于二维数组)
print(s[2][2])
#序列连接(两个列表组成新列表)
classmates  + [''lucy'', ''joe'']
#序列中的元素重复三次
classmates * 3
#元素在列表中是否存在
isHave = ''Bob'' in classmates
#转为序列(得到[''P'', ''y'', ''t'', ''h'', ''o'', ''n''])
list(''Python'')

tuple(元组)

一旦定义不可变。获取元素和 list 相同,如果元组中只有一个元素,必须补一个逗号,用于和运算符区分。

classmates = (''Michael'', ''Bob'', ''Tracy'')
# 单元素元组
classmates = (''Michael'',)

dict 和 set

dict

d = {''Michael'': 95, ''Bob'': 75, ''Tracy'': 85}
#取值(不存在报错)
d[''Michael'']
#取值,不存在返回`None` 
d.get(''Thomas'')
#取值,不存在返回自定义值`-1` 
d.get(''Thomas'', -1)
#定义值
d[''Adam''] = 67
#删除键值对
d.pop(''Bob'')
del (d[''Bob''])
#键列表
dict.keys()
#值列表
dict.values()
#键值对元组列表
dict.items()
#遍历
for (k, v) in dict.items():
    print ''dict[%s] ='' % k, v

####set 不重复的元素集合

<!--lang: python-->
#定义,需要将list转化为set,自动过滤重复
s = set([1, 2, 3])
#添加
s.add(4)
#删除
s.remove(4)
#交集
set([1, 2, 3]) & set([2, 3, 4])
#并集
set([1, 2, 3]) | set([2, 3, 4])

条件判断和循环

条件

elif 和 else 都可以省略。条件中非零数值、非空字符串、非空 list 等,就判断为 True,否则为 False

<!--lang: python-->
if <条件判断1>:
    <执行1>
elif <条件判断2>:
    <执行2>
elif <条件判断3>:
    <执行3>
else:
    <执行4>

循环

<!--lang: python-->
#遍历列表
names = [''Michael'', ''Bob'', ''Tracy'']
for name in names:
    print name

# 便利列表2
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
    print x

# 遍历列表3,等效2
for x in range(101):
    print x

# while循环(按条件循环)
n = 99
while n > 0:
    print n
    n = n - 2

1.python 基础篇 --- 监控股票

1.python 基础篇 --- 监控股票

使用 tushare 库

获取股票信息

1. 安装 tushare 库

  win+R 输入 cmd 进入控制台

  输入 pip install tushare

2. 获取股票信息

1 import tushare,time
2 #导入tushare库
3 data = tushare.get_realtime_quotes(‘000581’)
4 #获取股票代码为000581的股票信息
5 print(data)

 

3. 根据自定义要求,获取指定数据

因为 tushare 获取的返回值是一个 pandas 类型数据。可以用 loc 方式获取单独数据

data = tushare.get_realtime_quotes(share.code)
share.name = data.loc[0][0]
share.open = float(data.loc[0][1])
share.price = float(data.loc[0][3])
share.high = float(data.loc[0][4])
share.low = float(data.loc[0][5])

4.tushare 库详细用法

参考资料:http://tushare.waditu.com/trading.html

完整代码 -------------------------------------------------------------------

 1 import tushare,time
 2 
 3 def getrealtimedata(share):
 4     data = tushare.get_realtime_quotes(share.code)
 5     share.name = data.loc[0][0]
 6     share.open = float(data.loc[0][1])
 7     share.price = float(data.loc[0][3])
 8     share.high = float(data.loc[0][4])
 9     share.low = float(data.loc[0][5])
10     share.describe=''股票编号:{},股票名称:{},今日开盘价:{},当前价格:{},今日最高价:{},今日最低价:{}''.format(share.code,share.name,share.open,share.price,share.high,share.low)
11     return share
12 
13 class Share():
14     def __init__(self,code,buy,sale):
15         self.name = ''''
16         self.open = ''''
17         self.price = ''''
18         self.high = ''''
19         self.low = ''''
20         self.describe=''''
21         self.code = code
22         self.buy = buy
23         self.sale = sale
24 
25 def main(sharelist):
26     # share = Share(code)
27     for share in sharelist:
28         sss=getrealtimedata(share)
29         print(sss.describe)
30 
31         if sss.price <=sss.buy:
32             print(''价格超低,赶紧买入!'')
33         elif sss.price >= sss.sale:
34             print(''赶紧卖出。大赚了!'')
35         else:
36             print(''静观其变……'')
37 
38 while True:
39     share1=Share("000581",18.7,19.0)
40     share2=Share("600106",18.7,19.0)
41     share3=Share("000591",18.7,19.0)
42     sharelist = [share1,share2,share3]
43     main(sharelist)
44     time.sleep(5)

 

Angular2 Directive 学习笔记-基础篇

Angular2 Directive 学习笔记-基础篇

Angular2 Directive 学习笔记-基础篇

在Angular2中有三种类型的指令(Directive)
1. 组件 — 拥有模板的指令。
2. 结构型指令 - 通过添加和移除DOM元素来改变DOM结构的指令。例如:NgFor,NgIf …
3. 属性型指令 - 改变元素显示和行为的指令。例如:NgStyle …

Tips: 关于组件型的指令介绍会在专门的文章里面细致的介绍,毕竟Angular2中组件(Component)是如此的重要。

从创建一个简单属性型指令开始

在Angular2中,属性型指令的创建至少需要一个带有@Directive装饰器修饰的控制器类。@Directive装饰器指定了一个选择器名称,用于指出与此指令相关联的属性的名字。
控制器类实现了指令所具备的行为能力。接下来,开始创建一个简单的属性型指令,该指令的功能是,单鼠标在其修饰的元素上悬停时,改变其修饰元素的背景颜色。
创建一个highlight.directive.ts文件,其代码结构如下:

import { Directive,ElementRef,Renderer } from '@angular/core';

@Directive({
    selector: '[prefixHightlight]'
})
export class HighlightDirective {
    constructor(elem: ElementRef,renderer: Renderer) {
        renderer.setElementStyle(el.nativeElement,'backgroundColor','red');
    }
}

代码注解:

  1. 首先使用 import 语句从Angular Core库中导入我们需要使用的一些功能模块。
    使用 Directive 模块提供的 @Directive 修饰器,对 HighlightDirective 类进行功能修饰;
    在 HighlightDirective 类的构造函数中注入 ElementRef 和 Renderer 模块的实例(这里涉及到的DI-依赖注入关系之后也会有详细的学习笔记介绍)。
    注入 ElementRef 的目的在于让指令可以引用到真实的 DOM 元素。ElementRef这个类可以用来在宿主标签内注入其它标签的应用,这些应用并不仅仅局限于 DOM 元素。ElementRef这个类可以用来在宿主标签内注入其它标签的应用,这些应用并不仅仅局限于 DOM 元素。
    Renderer 可以让我们在 Hightlight 类里面的逻辑代码能够正确的渲染 DOM 元素的样式。
  2. 在倒入需要使用的功能模块后,我们使用@Directive装饰器以‘配置对象’参数的形式,对指令的元数据进行说明。
    属性型指令的@Directive装饰器需要一个css选择器来指定selector的值,以便Angular编译器从模版中识别出关联到这个指令的HTML。例如:代码中的‘[]’对应的就是css选择器中的属性选择器。
  3. 紧接着在@Directive元数据后面,我们声明并导出里指令的控制器类 HighlightDirective,HighlightDirective类包含了prefixHightlight指令的工作逻辑。别忘记了导出指令的控制器,
    这样才能够让我们定义的指令被别的指令(组件)访问。
  4. 需要注意的是:属性型指令的 selector 必须要对应 CSS 的属性选择器,同时命名需要遵循驼峰式命名方式
Tips: 在Angualr的最佳实践中推荐,
1. 我们应该为我们定义的每一个指令,组件,服务都添加上前缀。这样做的好处在于:
   确保我们自己声明定义的这些指令,组件,服务不会与标准的HTML属性冲突,也降低与第三方指令,组件,服务冲突的可能性。   
2. 指令的名称应该具备一定的自解释性,这样方便我们通过指令的名称就能大概知道指令的用途。

Angular会为每一个被指令匹配上的元素创建一个该指令对应的控制器类的实例。并自动注入该控制器类依赖的别的类的实例。比如上面的代码中,Angualr会选择合适的时机,为我们注入 ElementRef 和 Renderer 的实例。
Angular具体怎么实现的依赖注入之后的学习笔记会在一起学习,如果使用过Spring等Java框架的小伙伴一定对DI不会陌生的。ElementRef 是一个服务,它赋予了我们直接访问 DOM 元素的能力。
通过 ElementRef 的 nativeElement 属性和 Renderer 服务的组合使用,我们便实现了我们需要的指令能力。

如何使用属性型指令呢?

这个~~~对于Angualr2内置的指令的使用相信大家的已经用的不能在溜溜。我们这里学习一下如何在别的指令,组件中使用我们定义的组件的方法。
要使用我们刚才定义的指令,我们需要创建一个模板,并把这个指令作为一个属性应用到一个DOM元素上,也就是我们需要为我们定一个这个指令找到一个宿主元素。
我们先来定一个组件的模板,并取名字叫做:app.component.html

<h1>Angualr2 Directive Study</h1>
<article prefixHightlight>hover me</article>

模板定义完成后,我们开始定义我们的组件,将组件的文件名称定义为:app.component.ts,其代码结构如下:

import { Component,OnInit } from '@angualr/core';

@Component({
    selector: 'prefix-app',templateUrl: 'app.component.html'
})
export class AppComponent implements OnInit {
    constructor() {}

    ngOnInit(): void {
        console.log(`AppComponent has inited : ${ Date.Now() }`);
    }
}

接着我们声明一个Angular的模块,并在这个Angular模块中显示的声明我们自己定义的指令,以便Angualr在解析模板时,能够正确的识别我们自己定一个指令。
我们将模块的名称定义为:app.module.ts,其代码结构如下:

import { NgModule } from '@angular/core';
import { browserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { HighlightDirective } from './highlight.directive';

@NgModule({
  imports: [ browserModule ],declarations: [
    AppComponent,HighlightDirective
  ],bootstrap: [ AppComponent ]
})
export class AppModule { 

}

一定要记住在 @NgModule 的 declarations 数组中显示的声明我们定义的指令。否则,我们运行我们的应用时,浏览器会无情的跟我们抛出下面的错误提示:

EXCEPTION: Template parse errors:
Can’t bind to ‘prefixHighlight’ since it isn’t a kNown property of ‘article’.

简单的来总结一下自定义的属性型指令的运行原理:
Angular在编译模板时,检测到DOM元素上我们正在尝试绑定到某些属性 ,但Angualr并不能认识这些属性(非内置的属性指令)。
Angular就会尝试在我们声明的 declarations 元数据数组中查找这个指令属性。 我们把 HighlightDirective 在元数据的 declarations 数组中进行了声明,
这样一来 Angular 在发现这个指令的导入信息后,接着就会去检查对应的导入语句,从而找到 highlight.directive.ts 中导出的类,进而服务宿主元素对应的行为能力。

实现预定的目标

如果你动手实践了上面已经完成的代码,你会惊讶的发现,我们并没有实现我们最初设想的功能,我们仅仅是对使用了prefixHighlight指令的元素简单粗暴的设置了其背景颜色,
并没有实现预期的鼠标悬停在宿主元素上时才变换背景颜色的功能。
为了现实我们预期的目标,我们需要我们定义的指令能够感知到鼠标事件,并能够在这些事件触发时能够进行特定的行为。
下面我们就开始来改造我们的指令,找到highlight.directive.ts文件,并开始动手修改其代码结构如下:

import { Directive,Renderer,HostListener } from '@angular/core';

@Directive({
    selector: '[prefixHightlight]'
})
export class HighlightDirective {

    private _domElem: ElementRef;
    private _renderer: Renderer;

    constructor(elem: ElementRef,renderer: Renderer) {
        this._domElem = elem.nativeElement
        this._render = renderer;
        //renderer.setElementStyle(elem.nativeElement,'backgroundColor','red');
    }

    @HostListener('mouseenter')
    onMouseEnter() {
        this._render.setElementStyle(this._domElem,'red');
    }

    @HostListener('mouseleave')
    onMouseLeave() {
        this._render.setElementStyle(this.domElem,null);
    }
}

代码解释:

我们新导入了 HostListener 类,并使用了这个类的 @HostListener 装饰器。这个装饰器引用了我们定义的属性型指令的宿主元素,在我们的学习笔记中就是 \

如何封装功能强大的指令--让指令可做的事情更多

通过上面的修改,我们已经让我们定义的 prefixHighlight 指令具备了我们预期的功能。
但是我们还可以让它更加灵活和强大。接下来就让我们一起来让我们定义指令具备更丰富的能力能够做更多的事情,让它真正的实现‘器大活好’的目标。

我们需要的是灵活可配置的指令

现在我们实现的指令中高亮颜色是在指令中硬编码进去的,并没有弹性。 我们期望我们的指令是灵活的,这个颜色能够通过绑定从外部设置。例如:

<article [pefixHighlight]="yellow">hover me</article>

还是老规矩,先上代码,之后在解释。接着修改highlight.directive.ts文件,修改后其代码结构如下:

import { Directive,HostListener,Input } from '@angular/core';

@Directive({
    selector: '[prefixHightlight]'
})
export class HighlightDirective {

    private _domElem: ElementRef;
    private _renderer: Renderer;

    private _defaultColor = 'red';

    constructor(elem: ElementRef,'red');
    }

    @Input('prefixHighlight') highlightColor: string;

    @HostListener('mouseenter')
    onMouseEnter() {
        this._render.setElementStyle(this._domElem,this.highlightColor || this._defaultColor);
    }

    @HostListener('mouseleave')
    onMouseLeave() {
        this._render.setElementStyle(this._domElem,null);
    }
}

代码解释:

在上面的代码中,我们从 Angaulr Core 中新导入了 Input 模块,这个模块提供一个 @Input 装饰器,通过这个装饰器,使得我们的指令,能够接受外部的输入值,根据不同的输入值表现出不同的能力。
上面的代码中,我们定义了一个新的属性 highlightColor 并使用了 @Input 装饰器对其进行了装饰,这样一来 @Input 会把相关元数据添加到了类上,让 highlightColor 能被以 myHighlight 为别名进行绑定。
被 @Input 装饰器修饰的属性也被称为‘输入属性’。

通过上面的修改,我们基本实现了一个属性型指令的定义和使用,也简单粗暴的实现了一些指令输入的功能,由于时间关系(其实是学习程度的问题),这里先不做更深入的介绍,等我打完怪回来继续完善…
这篇学习笔记的结尾总感觉有点儿那什么,哎,算了。凑活看吧!以后打完怪在接着完善进阶篇,这样才有美剧的风格~~~~哈哈哈哈哈哈哈哈~~~~~

彩蛋吗???

额外的知识点:

上面的代码解释中提到了输入属性,这里就简单的介绍一下什么叫做输入属性吧。这样一来可以让这篇没有结尾的学习笔记看起来并没有哪吗突兀啦!
PS:关于 @Input @Output 的详细学习会在后面的进阶篇里面和大家一起学习

指令的 输入(Input)属性

我们在上面的最后一次修改中添加的 highlightColor 属性是 HighlightDirective 指令的一个 input 属性。
为了更好的理解为什么需要输入属性这个东西,我们需要先理解一下,
Angular在绑定的绑定的目标 之间的一个巧妙但重要的区别。
关于目标的一个简单定义:

如果属性出现在了模板表达式等号 (=) 的右侧,它就是一个。如果它出现在了方括号 ([ ]) 中,并且出现在等号 (=) 的左侧,它就是一个目标**

就像在绑定到 HighlightDirective 的 myHighlight 属性时所做的那样。

<p [prefixHighlight]="color">hover me</p>

[prefixHighlight]=”color” 中的 ‘color’ 就是绑定源属性不需要特别声明
[prefixHighlight]=”color” 中的 ‘prefixHighlight’ 就是绑定目标。 必须把它定义为一个 Input 属性,否则,Angular 就会拒绝这次绑定,并给出一个明确的错误。

当前只需要记住,通过@Input装饰的输入声明可以确保指令的消费者只能绑定到公开的 API 中的属性,而不是其它的属性。有效的保护了指令或组件的封装性。

Kubernetes 学习笔记-基础篇

Kubernetes 学习笔记-基础篇

Kubernetes 学习笔记,是个人学习记录文章,主要内容为摘录、总结和自己实践的记录,希望能帮助到和我一样正在学习的朋友。作为学习笔记,难免有理解不到位的地方,还请指正。

Kubernetes 学习笔记-基础篇

容器发展史

容器发展到今天,已成为各大公司保障快速响应复杂业务场景的利器。,容器发展简史,可通过下面这张图简单了解容器技术。

(图片来源:https://searchcloudcomputing.techtarget.com/tip/The-future-of-the-Kubernetes-ecosystem-isnt-all-about-cloud)

网上能找到大量的资料,这里找了些不错的资料,可以参考:

  • 40 年回顾,一文读懂容器发展史 - InfoQ [1]
  • 漫谈容器发展史 - 兔子先生 [2]
  • 容器发展简史 - 英文版 [3]
  • 容器发展简史 - 中译版 [4]

Kubernetes 简介

Kubernetes ,简称K8S,是Google在2014年6月开源的一个容器集群管理系统,K8S主要用于自动化部署、扩展和管理容器应用,提供了资源调度、部署管理、服务发现、扩容缩容、监控等一套功能,Kubernetes目标是让部署容器化应用更简单。

K8S,这是一种数字缩写 (Numeronym) 方式。类似的如internationalization(国际化) 叫做i18naccessibility叫做a11y

Kubernetes 主要有以下特性:

自我修复

在节点故障时重新启动失败的容器,替换和重新部署,保证预期的副本数量,杀死健康检查失败的容器,并且在未准备好之前不会处理客户端请求,确保线上服务不中断

弹性伸缩

使用命令、UI或者基于CPU使用情况自动快速扩容和缩容程序实例,确保应用服务高峰并发时的高可用性,业务低峰时回收资源,以最小成本运行服务,这个比较流啤

自动部署和回滚

K8S采用滚动更新策略更新应用,一次更新一个Pod,如果过程中出现问题,将回滚更改,保证升级不会影响业务

服务发现和负载均衡

K8S为多个容器提供一个统一访问入口(内部IP地址和一个DNS名称),并且负载均衡关联所有容器,使用户无需考虑容器IP问题。

机密和配置管理

管理机密数据和应用程序配置,而不需要把敏感数据暴露在镜像里,提高敏感数据安全性,并可以将一些常用的配置存储在K8S里,方便应用程序使用。

存储编排

挂载外部存储系统,无论是来自本地存储,公有云,还是网络存储(如NFS)都作为集群资源的一部分使用,极大提高存储使用的灵活性。

批处理

提供一次性任务,定时任务,满足批量数据处理和分析场景。

Kubernetes 架构组件

Kubernetes 集群架构可按角色分为Master 和 Node ,简单的架构图下图所示:

(图片来源:https://thenewstack.io/kubernetes-an-overview/)

Master 节点

Master 节点主要包括如下组件:

  • Kube-apiserver
    • Kubernetes API 集群统一入口,各组件协调者,以RESTful API 提供接口服务,所有对象资源的增删改查和监听都交给 APIServer处理后在提交给 Etcd存储。
  • kube-controller-manager
    • 处理集群中常规后台任务,一个资源对应一个控制器,而Controller Manager 就是负责管理这些控制器的。管理维护集群的状态,比如故障检测、自动扩展、滚动更新等
  • kube-scheduler
    • 根据调度算法为新创建的 Pod选择一个 Node节点,可以任意部署,可以部署在同一个节点上,也可以部署在不同的节点上。
  • etcd
    • 分布式键值存储系统,用户保存集群状态数据,比如 PodService等对象信息

Node 节点

  • kubelet
    • MasterNode节点上的 Agent,管理本机运行容器的生命周期,如创建容器, Pod挂载数据卷,下载 secret、获取容器和节点状态等工作, kubelet将每个 Pod转换成一组容器。
  • kube-proxy
    • Node节点上实现 Pod网络代理并执行链接转发,维护网络规则和四层负载均衡工作。
  • 容器运行时(docker 或 rocket)
    • 容器引擎,运行容器

kubernetes 核心概念

Pod

  • 最小部署单元
  • 一组容器的集合
  • 一个Pod中的容器共享网络命名空间
  • Pod是短暂的

Controllers控制资源

  • ReplicaSet:确保预期的Pod副本数量
  • Deployment:无状态应用部署
  • StatefulSet:有状态应用部署
  • DaenonSet:确保所有的 Node运行同一个 Pod
  • Job:一次性任务
  • Cronjob:定时任务
  • 更高层次对象,部署和管理Pod

Service

  • Pod 得上层统一访问入口,防止pod 扩缩容后ip或端口变化后失联。
  • 定义一组Pod访问策略:ClusterIP、NodePort 、LoadBalancer等。

Label

  • 标签,附加到某个资源上,用于关联对象,查询和筛选

Namespaces

  • 命名空间,将对象逻辑上隔离

Annotations

  • 注释

至此,Kubernetes 基本概念学习完成了。后续我会根据自己对K8S的理解不定期更新,也请期待后续的学习笔记。希望能帮助到学习K8S的同学,欢迎留言交流,共同学习。

扩展阅读

  • Kubernetes官网[5]

  • KUBERNETES: AN OVERVIEW[6]

  • Kubernetes基础篇 - 小明明S À DOMICILE[7]

  • Kubernetes配置管理最佳实践[8]

  • Kubernetes初体验[9]

参考资料

[1]

40 年回顾,一文读懂容器发展史 - InfoQ: https://www.infoq.cn/article/SS6SItkLGoLExQP4uMr5

[2]

漫谈容器发展史 - 兔子先生: https://liupzmin.com/2019/11/06/docker/container-chat/

[3]

容器发展简史 - 英文版: https://medium.com/faun/the-missing-introduction-to-containerization-de1fbb73efc5

[4]

容器发展简史 - 中译版: http://dockone.io/article/8832

[5]

Kubernetes官网: https://kubernetes.io

[6]

KUBERNETES: AN OVERVIEW: https://thenewstack.io/kubernetes-an-overview/

[7]

Kubernetes基础篇 - 小明明S À DOMICILE: https://www.dongwm.com/post/use-kubernetes-1

[8]

Kubernetes配置管理最佳实践: http://www.k8smeetup.com/article/VyaHa$XRm

[9]

Kubernetes初体验: https://www.qikqiak.com/k8s-book/docs/14.Kubernetes%E5%88%9D%E4%BD%93%E9%AA%8C.html


本文分享自微信公众号 - 码农吴先生(CoderMrWu)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

mysql 学习笔记--基础篇

mysql 学习笔记--基础篇

基础篇

Day 1

01 | 基础架构:一条SQL查询语句是如何执行的?
  • MySQL 可以分为 Server 层和存储引擎层两部分。

image.png
image.png
image.png

  • 尽量使用长连接,避免内存过大没释放的办法

image.png

  • 不要使用查询缓存
  • 总结,sever层:连接器,分析器,优化器,执行器

Day2

02 | 日志系统:一条SQL更新语句是如何执行的?
  • 与查询流程不一样的是,更新流程还涉及两个重要的日志模块
  • redo log(重做日志)和 binlog(归档日志)
  • WAL 的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘,也就是先写粉板,等不忙的时候再写账本
  • 当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log(粉板)里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面
  • innoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB,那么这块“粉板”总共就可以记录 4GB 的操作
  • image.png
  • 浅色框表示是在 InnoDB 内部执行的,深色框表示是在执行器中执行的

image.png

  • 两阶段提交(上图后3步)将 redo log 的写入拆成了两个步骤:prepare 和 commit
  • image.png
  • image.png

Day3

03 | 事务隔离:为什么你改了我还看不见?
  • ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性)
  • 现在用的是,mysql5.6 默认是 可重复读(repeatable read)

image.png

  • 对于一些从 Oracle 迁移到 MySQL 的应用,为保证数据库隔离级别的一致,你一定要记得将 MySQL 的隔离级别设置为“读提交”
  • image.png

Day4

04 05 | 深入浅出索引
  • 索引模型:哈希表、有序数组和搜索树
  • 每一个索引在 InnoDB 里面对应一棵 B+ 树。
  • 普通索引查询方式,则需要先搜索 k 索引树,再到 ID 索引树搜索一次。这个过程称为回表
  • 基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询
  • 一般需要用自增量设置主键 NOT NULL PRIMARY KEY AUTO_INCREMENT
  • KEY-VALUE类型可以不用自增量,直接设置KEY为主键
  • 覆盖索引:查询选择的列已经在普通索引树上,就不需要回表
  • 最左前缀:不只是索引的全部定义,只要满足最左前缀,就可以利用索引来加速检索 例如 name like ''朱%'',name的索引也起作用
  • 联合索引:(a,b) 符合最左前缀,mysql5.6后可以索引下推,减少回表次数。

Day5

06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍?
  • 全局锁:官方自带的逻辑备份工具是 mysqldump。当 mysqldump 使用参数–single-transaction 的时候,导数据之前就会启动一个事务,来确保拿到一致性视图。innoDB引擎支持,如果是MyISAM就需要用Flush tables with read lock (FTWRL)加全局锁再备份。
  • 表级锁:表锁的语法是 lock tables … read/write
  • 表级锁:元数据锁 MDL(metadata lock)。MDL 不需要显式使用,在访问一个表的时候会被自动加上。MDL 的作用是,保证读写的正确性
  • image.png
  • alert 字段会有写锁,频繁读取的表如果添加字段会造成现成堵塞。
  • image.png
07 | 行锁功过:怎么减少行锁对性能的影响?
  • 两阶段锁协议:在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。如果事务要锁多行,建议要把访问最多的那个锁放在最后执行。
  • 死锁 死锁检测:
  • image.png

Day6

08 | 事务到底是隔离的还是不隔离的?
  • InnoDB 的行数据有多个版本,每个数据版本有自己的 row trx_id,每个事务或者语句有自己的一致性视图。普通查询语句是一致性读,一致性读会根据 row trx_id 和一致性视图确定数据版本的可见性。
  • InnoDB 利用了“所有数据都有多个版本”的这个特性,实现了“秒级创建快照”的能力。

关于Python 学习笔记 - 基础篇python初学笔记的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于1.python 基础篇 --- 监控股票、Angular2 Directive 学习笔记-基础篇、Kubernetes 学习笔记-基础篇、mysql 学习笔记--基础篇的相关信息,请在本站寻找。

本文标签:

上一篇Pycharm 常用的小技巧汇总,Python 新手上路必备,快上车!(pycharm新手使用教程)

下一篇深度学习之 numpy.poly1d () 函数(numpy polyfit函数)