NRW算法是基于Quorum机制的是一种CP(Consistency&Partion tolerance)算法。
NWR策略(又称为Quorum仲裁协议),其中,N为数据的副本总数,W为更新一个数据对象时需要确保成功更新的份数,R为读取一个数据时需要读取的副本个数。
如果W+R>N, 那么久可以保证某个数据不能被两个不同的事物同时读/写。否则,如果有两个事物同时对同一数据进行读/写,那么在W+R>N的情况下,至少会有一个副本发生读/写冲突。
如果W>N/2, 那么可以保证两个事务不能并发写同一个数据,否则,至少会有一个副本发生写冲突。
强一致性:NRW中N=W, R=1, 比如313,616。
弱一致性:NRW中N!=W, R+W>N, 比如634。
最终一致性:暂时有段时间副本之间不一致,但是最终会成为一致。NRW中,N+W<=N, NRW=311
N: 数据复制的份数。
W:更新数据是需要保证写完成的节点数。
R:读取数据的时候需要读取的节点数。
一般采取N = 3, R = 2, W =2。
N至少达到3,大于3则付出更高的成本。小于3无法保障高可用。
W = 2 可以保障大多数写成功。 W未必等于N,则一定存在数据不一致的情况。 冲突解决策略一般有Cassandra使用的client tiemstamps和Riak的Vector clock等,如果无法解决,冲突可能会硬性覆盖或者推到业务代码。
R = 2 能保障读到大多数一致的最新版本。
Quorum机制与NRW算法
https://blog.csdn.net/jeffsmish/article/details/54171812
进程的 PID 不停在变,要么是这些进程在不停地重启,要么就是全新的进程,这无非也就两个原因:
第一个原因,进程在不停地崩溃重启,比如因为段错误、配置错误等等,这时,进程在退出后可能又被监控系统自动重启了。进程本身在不停地崩溃重启,而启动过程的资源初始化,很可能会占用相当多的 CPU。
第二个原因,这些进程都是短时进程,也就是在其他应用内部通过 exec 调用的外面命令。这些命令一般都只运行很短的时间就会结束,很难用 top 这种间隔时间比较长的工具发现。
一般当进程非正常退出时,会生成一个core文件,这个文件是进程猝死时内存的转储文件,也称为core dump。
core文件生成时间长,会导致业务进程一直挂着,会导致业务中断。
看是由什么信号触发
常见的段错误信号 4, 7, 11
每个信号都有一个名字和编号,这些名字都以“SIG”开头,例如“SIGIO”, “SIGCHLD”等等。信号定义在signal.h投文件中,信号名都定义为正整数。
具体的信号名称可以使用kill -l来查看信号的名字以及序号,信号是从1开始编号的,不存在0号信号。kill对于信号0有特殊的应用。
表:term:信号终止进程;core:进程产生核心存储文件并退出;ignore:忽略该信号;stop:信号停止了进程;cont:信号恢复了一个已停止的进程
名 称 | 信 号 值 | 描 述 | SUSv3 | 默认 |
---|---|---|---|---|
SIGABRT | 6 | 中止进程 | ● | core |
SIGALRM | 14 | 实时定时器过期 | ● | term |
SIGBUS | 7(SAMP = 10) | 内存访问错误 | ● | core |
SIGCHLD | 17(SA=20,MP=18) | 终止或停止子进程 | ● | ignore |
SIGCONT | 18(SA=19,M=25,P=26) | 若停止则继续 | ● | cont |
SIGEMT | undef(SAMP=7) | 硬件错误 | term | |
SIGFPE | 8 | 算术异常 | ● | core |
SIGHUP | 1 | 挂起 | ● | term |
SIGILL | 4 | 非法指令 | ● | core |
SIGINT | 2 | 终端中断 | ● | term |
SIGIO | 29(SA=23,MP=22) | I/O时可能产生 | ● | term |
SIGPOLL | ||||
SIGKILL | 9 | 必杀(确保杀死) | ● | term |
SIGPIPE | 13 | 管道断开 | ● | term |
SIGPROF | 27(M=29,P=21) | 性能分析定时器过期 | ● | term |
SIGPWR | 30(SA=29,MP=19) | 电量行将耗尽 | term | |
SIGQUIT | 3 | 终端退出 | ● | core |
SIGSEGV | 11 | 无效的内存引用 | ● | core |
SIGSTKFLT | 16(SAM=undef,P=36) | 协处理器栈错误 | term | |
SIGSTOP | 19(SA=17,M=23,P=24) | 确保停止 | ● | stop |
SIGSYS | 31(SAMP=12) | 无效的系统调用 | ● | core |
SIGTERM | 15 | 终止进程 | ● | term |
SIGTRAP | 5 | 跟踪/断点陷阱 | ● | core |
SIGTSTP | 20(SA=18,M=24,P=25) | 终端停止 | ● | stop |
SIGTTIN | 21(M=26,P=27) | 后台进程组从终端读取 | ● | stop |
SIGTTOU | 22(M=27,P=28) | 后台进程组向终端写 | ● | stop |
SIGURG | 23(SA=16,M=21,P=29) | 套接字上的紧急数据 | ● | ignore |
SIGUSR1 | 10(SA=30,MP=16) | 用户自定义信号1 | ● | term |
SIGUSR2 | 12(SA=31,MP=17) | 用户自定义信号2 | ● | term |
SIGVTALRM | 26(M=28,P=20) | 虚拟定时器过期 | ● | term |
SIGWINCH | 28(M=20,P=23) | 终端窗口尺寸发生变化 | ignore | |
SIGXCPU | 24(M=30,P=33) | 突破对CPU时间的限制 | ● | core |
SIGXFSZ | 25(M=31,P=34) | 突破对文件大小的限制 | ● | core |
Kill -9一般不会生成core
信号15是主动杀
信号6一般是abort
信号11 是内存引用问题。(比如:指针为空)
如果有 core,则搜日志 “Signal captured” 或 “Assert”;
网络问题中,比较容易出现core问题。
没有core: 说明他们自身没有产生core的机制。
core生成原理,如果信号没有捕获到,也不会生成;还有一种可能性是不是信号量阻塞了。
原因可能如下:
1、没有开启 core:ulimit -c 如果显示为0是没有开启 core 的。
2、没配 core_pattern 路径。
解决方法:
gdb
(gdb) set sysroot /tmp/lib
(gdb) set solib-search-path /tmp/lib:/lib64
(gdb) file [二进制文件]
(gdb) core /tmp/corefiles/core-***
t a a bt查看所有线程堆栈
https://blog.csdn.net/liubangbo/article/details/84841181
https://blog.csdn.net/pcj_888/article/details/106882370
data 目录下面的 diag 目录下找下有没有 blackbox 目录,里面也有 trace 栈
1.blog.csdn.net/shaovey/article/details/2744487
Linux下core文件调试方法
2.andyniu.iteye.com/blog/1965571
linux下生成core dump文件调试方法及设置
3.信号概述
netstat –help
netstat -anltu
netstat -anplt
netstat –nplt
netstat -tnpl
netstat -atun | grep 被测试机器的IP地址 |
-a 显式所有的socket
linux下进程、端口号相互查看方法
https://www.cnblogs.com/MacoLee/p/5664306.html
ps -ef | grep 进程名 |
netstat -nap | grep 进程pid |
linux通过端口查看进程:
netstat -nap | grep 端口号 |
查看网卡的丢包记录
netstat -i
输出中的 RX-OK、RX-ERR、RX-DRP、RX-OVR ,分别表示接收时的总包数、总错误数、进入Ring Buffer 后因其他原因(如内存不足)导致的丢包数以及 Ring Buffer 溢出导致的丢包数。
TX-OK、TX-ERR、TX-DRP、TX-OVR 也代表类似的含义,只不过是指发送时对应的各个指标。
ARP协议(地址解析协议)属于数据链路层的协议,主要负责根据网络层地址(IP)来获取数据链路层地址(MAC)。
借助Scapy来编写ARP主机发现脚本,通过脚本对以太网内的每个主机都进行ARP请求。若主机存活,则会响应我们的ARP请求,否则不会响应。
Scapy中的ARP参数如下所示:
op代表消息类型:1为ARP请求,2为ARP响应 hwsrc代表源MAC地址 psrc代表源IP地址 hwdst代表目的MAC地址 pdst代表目的IP地址
Scapy中的Ether参数如下所示:
src表示源MAC地址
dst表示目的MAC地址
#!/usr/bin/python3
#-*- coding: utf-8 -*-
import os
import re
import optparse
from scapy.all import *
#取IP地址和MAC地址获取函数
def HostAddress(iface):
#os.popen执行后返回执行结果
ipData = os.popen('ifconfig '+iface)
#对ipData进行类型转换,再用正则进行匹配
dataLine = ipData.readlines()
#re.search利用正则匹配返回第一个成功匹配的结果,存在结果则为true
#取MAC地址
global MAC
global IP
if re.search('\w\w:\w\w:\w\w:\w\w:\w\w:\w\w',str(dataLine)):
#取出匹配的结果
MAC = re.search('\w\w:\w\w:\w\w:\w\w:\w\w:\w\w',str(dataLine)).group(0)
#取IP地址
if re.search(r'((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)',str(dataLine)):
IP = re.search(r'((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)',str(dataLine)).group(0)
#将IP和MAC通过元组的形式返回
addressInfo = (IP,MAC)
return addressInfo
#ARP扫描函数
def ArpScan(iface='eth0'):
# 通过HostAddres返回的元组取出MAC地址
mac = HostAddress(iface)[1]
#取出本机IP地址
ip = HostAddress(iface)[0]
#对本机IP地址进行分割并作为依据元素,用于生成需要扫描的IP地址
ipSplit = ip.split('.')
#需要扫描的IP地址列表
ipList = []
for i in range(1,255):
ipItem = ipSplit[0] + '.' + ipSplit[1] + '.' + ipSplit[2] + '.' + str(i)
ipList.append(ipItem)
'''
发送ARP包
因为要用到OSI的二层和三层,所以要写成Ether/ARP。
因为最底层用到了二层,所以要用srp()发包
'''
result=srp(Ether(src=mac,dst='FF:FF:FF:FF:FF:FF')/ARP(op=1,hwsrc=mac,hwdst='00:00:00:00:00:00',pdst=ipList),iface=iface,timeout=2,verbose=False)
#读取result中的应答包和应答包内容
resultAns = result[0].res
#存活主机列表
liveHost = []
#number为接收到应答包的总数
number = len(resultAns)
print("=========================")
print("ARP 探测结果")
print("本机IP地址:" + ip)
print("本机MAC地址:" + mac)
print("=========================")
for x in range(number):
IP = resultAns[x][1][1].fields['psrc']
MAC = resultAns[x][1][1].fields['hwsrc']
liveHost.append([IP,MAC])
print("IP:" + IP + "\n\n" + "MAC:" + MAC )
print("============================")
# 把存活主机IP写入文件
resultFile = open("result","w")
for i in range(len(liveHost)):
resultFile.write(liveHost[i][0] + "\n")
resultFile.close()
if __name__ == '__main__':
parser = optparse.OptionParser('usage: python %prog -i interfaces \n\n' 'Example: python %prog -i eth0\n')
#添加网卡参数 -i
parser.add_option('-i','--iface',dest='iface',default='eth0',type='string', help='interfaces name')
(options,args) = parser.parse_args()
ArpScan(options.iface)
脚本测试结果如下:
查看结果文件如下所示:
1、使用原生的开源工具Valgrind,可以参考官网:http://www.valgrind.org/
2、现主要使用该工具检测以下问题:
(1)写越界导致的踩内存问题
(2)内存free后仍在使用的问题
(3)错误使用未初始化内存
Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任务。
Valgrind允许用户分析(profile)和调试Linux上的可执行程序。
Valgrind包含的内存检查工具Memcheck可以检测常见的内存错误。此类错误包括访问无效的内存,使用未初始化的值,不正确的释放内存,以及内存泄漏。然而,Memcheck不对静态数组的边界进行检查。
内存泄漏可以允许攻击者在受影响的程序上进行拒绝服务。
https://zhuanlan.zhihu.com/p/342958592 内存错误修复指南