写点什么

【架构师训练营 - week8 -2】总结

用户头像
早睡早起
关注
发布于: 2020 年 07 月 29 日

OSI七层协议



OSI七层网络模型TCP/IP四层概念模型对应网络协议应用层(Application)应用层HTTP、TFTP, FTP, NFS, WAIS、SMTP表示层(Presentation)Telnet, Rlogin, SNMP, Gopher会话层(Session)SMTP, DNS传输层(Transport)传输层TCP, UDP网络层(Network)网络层IP, ICMP, ARP, RARP, AKP, UUCP数据链路层(Data Link)数据链路层FDDI, Ethernet, Arpanet, PDN, SLIP, PPP物理层(Physical)IEEE 802.1A, IEEE 802.2到IEEE 802.11



在物理层,我们要解决两台物理机之间的通信需求,互相能收到比特流。以电流强弱的形式来表示传0还是1。



在数据链路层,基本保证了数据的可靠传输。



在网络层,主要是进行路由的选择与转换。



在传输层,定义了TCP协议和UDP协议,提供端到端的传输。



在会话层, 管理主机之间的会话进程 。



在表示层, 定义数据格式及加密即对上层数据或信息进行变换以保证一个主机应用层信息可以被另一个主机的应用程序理解。



在应用层,都是用户的应用程序。



三次握手



概述



我们都知道网络是通过,TCP/IP协议传输的。IP协议是无连接的通信协议,是不可靠的通信协议,它会把消息或者数据分割成较小的数据包,但是通过路由传输到目的地的过程是没有机制去检测数据的正确性和数据是否丢失。这时候就需要它的上层协议TCP来保证数据的可靠性。



TCP协议是面向连接的,可靠的,面向字节流的传输层数据结构。它是以MPU作为数据分割的最大单元,它会给每个包设置一个Sequence Number,保证数据的有序性和是否丢失,当接收端收到数据之后,会返回一个ACK。当发送端在ITT时间内没有收到ACK,就证明这个数据丢失了,会进行重传。TCP还设置了奇偶校验和函数来检验数据是否有错误,在发送和接收的时候都要校验和。



再说TCP报文首部



报文首部

源端口/目的端口,Source port/Destination port是协议端口号,ip协议中的ip地址可以唯一标识一个主机,TCP协议中的协议端口,可以唯一标识一个进程。IP地址加协议加端口号可以唯一表示一个网络进程,把这种模式叫做套接字Socket.



序列号,SequeceNumber就是数据包的序号,占4个字节。



确认号,ACK就是应答序号,指的是期望下次收到的数据,如接收到的sequeceNumber为105,数据长度为200,ACK设置的值就为305.



首部长度,offset为偏移量,指的是第一个数据包距离TCP首部的位置,设置这个值的原因是因为header的数据长度是不固定的。



URG:紧急指针标志,为1表示有效,0忽略



ACK:确认序号标志,1确认号有效,0不包含确认号



PSH:push标志,为1,指当接收端收到这个程序时候应该尽快把数据发送给应用程序。而不是在缓存中排队。



RST:重置连接标志,主机奔溃或者一些原因的错误连接,或者是非法连接。



SYN:同步序列号,用来建立连接过程



FIN:finish标志,用于释放连接



Window窗口,滑动窗口,指的是发送端和接收端缓存的大小,控制发送端流量的控制



校验和 CheckSum,用来纠错,在发送端生成,在接收端进行验证。



三次握手的过程



三次握手.png

三次握手采用全双工的通信方式



  • 第一次握手:建立连接的时候,客户端发送SYN包到服务器,并进入SYN_SENG状态,等待服务器的确认

  • 第二次握手:服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入了SYN_RECV状态。

  • 第三次握手:客户端收到了服务器的SYN+ACK包,向服务器发送ACK(ack=k+1),此时包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。



为什么进行三次握手



首先是为了初始化Sequence Number的初始值。当Server收到Client的SYN,回复SYN_ACK后,没收到ACK,server不断进行重试操作,直到63秒超时,计算的时间是翻倍增加,分别为2,4,8,16,32。才会断开连接。



引起的问题SYN Flood的防护措施



当有人而已攻击,恶意请求服务器导致耗尽连接队列。这时候如果SYN队列满了,通过tcp_syncookies参数回发SYN Cookie,若为正常连接则Client会回发SYN Cookie,直接建立连接。



保活机制



如果建立了连接,但是客户端忽然故障,服务端会在超时后每隔75秒发送10次保活探针报文,如果未收到响应则继续发送,尝试次数达到保活探测数量,仍然未收到,则断开连接。



四次挥手



四次挥手.png

客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定FIN报文段即使不携带数据,也要消耗一个序号。

服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗

MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。



为什么关闭连接是四次握手呢?



这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。



为什么要等2MSL后才能返回到CLOSED状态?



这是因为虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文 。



1.索引是什么呢?



数据库索引是一种数据结构,它以维护索引数据结构的额外写操作和存储空间为代价,提高了对数据库表进行数据检索操作的速度。索引用于快速定位数据,而不必每次访问数据库表时都在数据库表中搜索每一行。可以使用数据库表的一列或多列来创建索引,这为快速随机查找和有效访问有序记录提供了基础。

​ --Wiki翻译版



对于相关专业的人来说,这个问题很好回答。我们在理解上可以认为索引就是类似于字典目录一样的东西,通过它可以快速定位到数据。



2.索引的数据结构是什么呢?



在MySQL中使用的数据结构为B+树作为索引,我们可以简单来分析下为什么要使用B+树作为索引呢?



前提假设你知道二叉树的基本知识:左小右大,无节点相等



假如使用二叉树作为索引,这样做的不好处是,会形成一个极端的查询树

极端二叉树



  • 使用AVL树的作为索引,这样做的不好处是,它是一个平衡二叉树,当对数据进行一些删除增加操作的时候,AVL树会使用旋转的方式来调整树结构。这样来看,维护这颗树的代价过于高昂。

  • 使用红黑树最为索引,这样做的不好处

  • 使用B树作为索引,和B+树相比这样的不好处是



这就是为什么使用B+树作为索引的原因。



3.既然Hash所以查询速率只有O(1),为什么不使用?



1.Hash索引在最好的情况下会是O(1)的查询效率,但是当一些极端情况下,也会导致大量数据存在一个Bucket中,所以查询速率不一定比B+树快。



2.Hash索引不能进行范围查询,不能进行排序。



3.Hash索引不能进行组合索引中的部分索引查询。



4.不能避免表扫描,因为通过Hash值查找到链表之后,还是得通过实际值对比才能确认。



4.位图索引是什么?



位图索引和布隆过滤器的设计结构有点相似,简单来说就是使用0 1的方式来进行数据类型或者值的判定。由于这种特性,位图索引在进行读写操作的时候,必须严格使用强锁进行操作。所以它的一个缺点就是不适合高并发的操作下的数据库读写操作。适合统计运算较多。



5.密集索引和稀疏索引的区别是什么?



1.密集索引文件中的每个搜索码值都对应一个索引值。



密集索引决定了表中的物理排列顺序。在InnoDB中有且只有一个密集索引,主键被定义了,主键就是唯一索引。若没有唯一非空索引,InnoDB内部就会生成一个隐藏主键。



select * from person where id = 7;


例如之上的sql语句就会直接走密集索引查询到相关的行。



稀疏索引查询的流程是先查找到它的id,然后再去密集索引查找到具体的行。例如:



select * from person where age=18;


在查询的内部操作中,是先查找到age=18对应的所有数据的id,然后再走密集索引的方式查找的所属的行。



6.联合索引最左匹配原则的成因?



最左前缀匹配原则,非常重要的原则,MySQL会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。=in可以乱序,比如a = 1 and b = 2 and c = 3建立(a,b,c)索引可以任意顺序,MySQL的查询优化器会帮你优化成索引可以识别的形式。



联合索引最左匹配原则的成因是因为,联合所以需要在第一个索引字段上进行排序,在第一个字段的基础上对第二个字段进行查找。所以第二个字段是用不到索引的。



7.索引是建立的越多越好么?



数据量小的表不需要建立索引,建立所以会增加开销。



用户头像

早睡早起

关注

还未添加个人签名 2019.09.05 加入

还未添加个人简介

评论

发布
暂无评论
【架构师训练营 - week8 -2】总结