Configuration
1 | #Disable discovery |
Reference
- [服务注册和服务发现-Eureka的常用配置] https://yq.aliyun.com/articles/138261
1 | #Disable discovery |
This will make the container execute internally as the root user.
1 | containers: |
1 | apiVersion: v1 |
In the CLI, the access modes are abbreviated to:
1 | - protocol: TCP |
min k8s version:v1.10.0
equal to docker run –privileged
1 | - name: APP_NAME |
应用场景
spec.updateStrategy.type
spe.updateStrategy.rollingUpdate.partition 金丝雀策略
通过volumeClaimTemplates关联创建PV,volumeMounts使用PV
而HTTP劫持很容易解决,那就是加上SSL证书,网站链接全部内容加密,这样“检查站:墙”就无法解密数据分析关键词了。但是这不是绝对能解决这个问题的,如果你的网站只是误杀或者违规擦边球,那还好,如果是大型网站,就会特殊对待了。
HTTPS在建立加密连接的时候,需要一次握手,也就是达成链接协议建立加密连接,但是这次握手是明文的(建立加密链接首先就是链接双方信任,比如网站的SSL证书是自己签的,或者SSL证书到期或伪造的,在访问这个网站的时候浏览器就会进行提示,表示此网站不安全啥的。
握手是明文的就意味着,如果你的域名被重点关注,即使你加上了SSL证书,也会在首次握手的时候,被关键词匹配然后掐断链接。还有一种方式,就是域名备案,使用国内服务器。这样用户在访问你的网站时,根本不需要经过墙,自然也没有了拦截。
LLVM is Low Level Virtual Machine.
LLVM可以被看作是一系列的编译器和工具链技术的集合,而且它们是模块化并且是可重用的。
原话是:The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
特性
特别注意:LLVM不是只用来实现编译优化的!
LLVM架构的主要组成部分如下(事实上也是所有现代编译器架构):
前端 -> 流程(Pass) -> 后端
前端获取你的源代码然后将它转变为某种中间表示。这种翻译简化了编译器其他部分的工作,这样它们就不需要面对比如C++源码的所有复杂性了。作为一个豪迈人,你很可能不想再做这部分工作;可以不加改动地使用Clang来完成。
“流程”将程序在中间表示之间互相变换。一般情况下,流程也用来优化代码:流程输出的(中间表示)程序和它输入的(中间表示)程序相比在功能上完全相同,只是在性能上得到改进。这部分通常是给你发挥的地方。你的研究工具可以通过观察和修改编译过程流中的IR来完成任务。
后端部分可以生成实际运行的机器码。你几乎肯定不想动这部分了。
虽然当今大多数编译器都使用了这种架构,但是LLVM有一点值得注意而与众不同:整个过程中,程序都使用了同一种中间表示。在其他编译器中,可能每一个流程产出的代码都有一种独特的格式。LLVM在这一点上对hackers大为有利。我们不需要担心我们的改动该插在哪个位置,只要放在前后端之间某个地方就足够了。
当执行完slaveof masterip port 命令时候,从库根据指明的master节点ip和port向主库发起socket连接,主库收到socket连接之后将连接信息保存,此时连接建立;
当socket连接建立完成以后,从库向主库发送ping命令,以确认主库是否可用,此时的结果返回如果是PONG则代表主库可以用,否则可能出现超时或者主库此时在处理其他任务阻塞那么此时从库将断开socket连接,然后进行重试;
如果主库连接设置了密码,则从库需要设置masterauth参数,此时从库会发送auth命令,命令格式为“auth + 密码”进行密码验证,其中密码为masterauth参数配置的密码,需要注意的是如果主库设置了密码验证,从库未配置masterauth参数则报错,socket连接断开。
当身份验证完成以后,从节点发送自己的监听端口,主库保存其端口信息,此时进入下一个阶段:数据同步阶段。
主库和从库都确认对方信息以后,便可开始数据同步,此时从库向主库发送psync命令(注意,redis4.0版本对2.8版本的psync做了优化),主库收到该命令后判断是进行增量复制还是全量复制,然后根据策略进行数据的同步,当主库有新的写操作时候,此时进入复制第三阶段:命令传播阶段。
redis采用量乐观复制策略,容忍在一定时间内主从数据内容是不同的,但是两者的数据最终会同步。
当数据同步完成以后,在此后的时间里主从维护着心跳检查来确认对方是否在线,每隔一段时间(默认10秒,通过repl-ping-slave-period参数指定)主节点向从节点发送PING命令判断从节点是否在线,而从节点每秒1次向主节点发送REPLCONF ACK命令,命令格式为:REPLCONF ACK {offset},其中offset指从节点保存的复制偏移量。作用一是汇报自己复制偏移量,主节点会对比复制偏移量向从节点发送未同步的命令,作用二在于判断主节点是否在线,从库接送命令并执行,最终实现与主库数据相同。
sync -> psync1 -> psync2
sync
在redis2.6以及以前的版本,复制采用sync命令,当一个从库启动后,会向主库发送sync命令,主库收到sync命令后执行bgsave后台保存RDB快照,同时将保存快照的将快照保存期间接受的写命令保存到缓冲队列。
当快照完成以后,主库将快照文件已经缓存的所有命令发送给从库,从库接受到快照文件并载入,再将执行主库发送的命令,也就是上面我们介绍的复制初始化阶段和数据同步阶段,其后就是命令增量同步,最终主库与从库保持数据一直。
当从库在某些情况断线重连(如从库重启、由于网络原因主从连接超时),重复上述过程,进行数据同步。由此可见,redis2.6版本以及2.6以前复制过程全部采用全量复制。
sync虽然解决了数据同步问题,但是在数据量比较大情况下,从库断线从来依然采用全量复制机制,无论是从数据恢复、宽带占用来说,sync所带来的问题还是很多的。于是redis从2.8开始,引入新的命令psync。
psync1
在redis2.8版本,redis引入psync命令来进行主从的数据同步,这里我们称该命令为psync1。
psync1实现依赖以下三个关键点:
主库和从库分别各自维护一个复制偏移量(可以使用info replication查看),用于标识自己复制的情况,在主库中代表主节点向从节点传递的字节数,在从库中代表从库同步的字节数。每当主库向从节点发送N个字节数据时,主节点的offset增加N,从库每收到主节点传来的N个字节数据时,从库的offset增加N。因此offset总是不断增大,这也是判断主从数据是否同步的标志,若主从的offset相同则表示数据同步量,不通则表示数据不同步。以下图示分别代表某个时刻两个主从的同步情况
复制积压缓冲区是一个固定长度的FIFO队列,大小由配置参数repl-backlog-size指定,默认大小1MB。需要注意的是该缓冲区由master维护并且有且只有一个,所有slave共享此缓冲区,其作用在于备份最近主库发送给从库的数据。
在主从命令传播阶段,主节点除了将写命令发送给从节点外,还会发送一份到复制积压缓冲区,作为写命令的备份。除了存储最近的写命令,复制积压缓冲区中还存储了每个字节相应的复制偏移量,由于复制积压缓冲区固定大小先进先出的队列,所以它总是保存的是最近redis执行的命令。
每个redis实例在启动时候,都会随机生成一个长度为40的唯一字符串来标识当前运行的redis节点,查看此id可通过命令info server查看。
当主从复制在初次复制时,主节点将自己的runid发送给从节点,从节点将这个runid保存起来,当断线重连时,从节点会将这个runid发送给主节点。主节点根据runid判断能否进行部分复制:
psync2
redis4.0新版本除了增加混合持久化,还优化了psync(以下称psync2)并实现即使redis实例重启的情况下也能实现部分同步,下面主要介绍psync2实现过程。psync2在psync1基础上新增两个复制id
- master_replid1: 复制id1(后文简称:replid1),一个长度为41个字节(40个随机串+’0’)的字符串,每个redis实例都有,和runid没有直接关联,但和runid生成规则相同。当实例变为从实例后,自己的replid1会被主实例的replid1覆盖。
- master_replid2:复制id2(后文简称:replid2),默认初始化为全0,用于存储上次主实例的replid1。
在4.0之前的版本,redis复制信息完全丢失,所以每个实例重启后只能进行全量复制,到了4.0版本,任然可以使用部分同步,其实现过程:
- 第一步:存储复制信息
redis在关闭时,通过shutdown save,都会调用rdbSaveInfoAuxFields函数,把当前实例的repl-id和repl-offset保存到RDB文件中,当前的RDB存储的数据内容和复制信息是一致性的可通过redis-check-rdb命令查看
- 第二步:重启后加载RDB文件中的复制信息
redis加载RDB文件,会专门处理文件中辅助字段(AUX fields)信息,把其中repl_id和repl_offset加载到实例中,分别赋给master_replid和master_repl_offset两个变量值,特别注意当从库开启了AOF持久化,redis加载顺序发生变化优先加载AOF文件,但是由于aof文件中没有复制信息,所以导致重启后从实例依旧使用全量复制!
- 第三步:向主库上报复制信息,判断是否进行部分同步
从实例向主库上报master_replid和master_repl_offset+1;从实例同时满足以下两条件,就可以部分重新同步,否则执行全量同步:
- 从实例上报master_replid串,与主实例的master_replid1或replid2有一个相等,用于判断主从未发生改变;
- 从实例上报的master_repl_offset+1字节,还存在于主实例的复制积压缓冲区中,用于判断从库丢失部分是否在复制缓冲区中;
psync2除了解决redis重启使用部分同步外,还为解决在主库故障时候从库切换为主库时候使用部分同步机制。redis从库默认开启复制积压缓冲区功能,以便从库故障切换变化master后,其他落后该从库可以从缓冲区中获取缺少的命令。该过程的实现通过两组replid、offset替换原来的master runid和offset变量实现
- 第一组:master_replid和master_repl_offset:如果redis是主实例,则表示为自己的replid和复制偏移量; 如果redis是从实例,则表示为自己主实例的replid1和同步主实例的复制偏移量。
- 第二组:master_replid2和second_repl_offset:无论主从,都表示自己上次主实例repid1和复制偏移量;用于兄弟实例或级联复制,主库故障切换psync。
判断是否使用部分复制条件:如果从库提供的master_replid与master的replid不同,且与master的replid2不同,或同步速度快于master; 就必须进行全量复制,否则执行部分复制。
以下常见的主从切换都可以使用部分复制:
- 一主一从发生切换,A->B 切换变成 B->A;
- 一主多从发生切换,兄弟节点变成父子节点时;
- 级别复制发生切换, A->B->C 切换变成 B->C->A;
原理
redis全量复制的原理是,首先将master本身的RDB文件同步给slave,而在同步期间,master写入的命令也会记录下来(master内部有一个复制缓冲区,会记录同步时master新增的写入),当slave将RDB加载完后,会通过偏移量的对比将这期间master写入的值同步给slave。
为什么要部分复制? 在redis2.8版本之前,如果master和slave之间的网络发生了抖动连接断开,就会导致slave完全不知道master的动作,同步就会出问题,而为了保证数据一致,等网络恢复后进行一次全量复制。而全量复制的开销是很大的,redis2.8版本就提个了一个部分复制的功能。
原理
当master和slave断开连接时,master会将期间所做的操作记录到复制缓存区当中(可以看成是一个队列,其大小默认1M)。待slave重连后,slave会向master发送psync命令并传入offset和runId,这时候,如果master发现slave传输的偏移量的值,在缓存区队列范围中,就会将从offset开始到队列结束的数据传给slave,从而达到同步,降低了使用全量复制的开销。
FEMA:故障模式与影响分析,一种在各行各业都有广泛应用的可用性分析方法,通过对系统范围内潜在的故障模式加以分析,并按照严重程度进行分类,以确定失效对于系统的最终影响。它是一套分析和思考的方法,而不是某个领域的技能或工具。
FMEA分析方法:
FMEA分析方法,其实是一个分析表,表格包含部分
遍历方式
一种平衡二叉查找树,增加和删除节点后通过树形旋转重新达到平衡。
一颗完美平衡的树查找树中,所有空节点到根节点的距离应该是相同的。
特性:
在每一次插入数值之后,树的平衡性都可能被破坏,这时可以通过一个简单的操作来矫正平衡–旋转。
旋转的目的就是减少高度,通过降低整棵树的高度来平衡。哪边的树高,就把那边的树向上旋转。
旋转操作
旋转类型
此时,节点7的左子树高度为2,右子树为0,则两边的差值超过1。
围绕节点5进行右旋转,因为节点5没有右子节点,此时可以直接把节点7设置为节点5的右子节点。需要注意的是,当调节完当前节点的平衡后,需要向上检查是否有节点出现不平衡的现象。
如果节点5已经存在右子树(节点7是节点5的父节点,肯定比节点5大,即也比节点5的右子节点大),此时节点7如何处理?请看下图
仍然针对节点5进行右旋,节点7仍然为节点5的右子树,节点6成为节点7的左子树,此时节点5已经平衡。但是当我们再看节点8的时候,节点8却失衡了。
如果节点13已经有左子树,怎么办?
如果节点5已经有左子树,怎么办?