自动登录ssh脚本

远程登录服务器,每次都要输命令-复制粘贴密码-切换目录,非常麻烦,于是上网查了一下有没有自动登录的脚本,果然有,研究了一下,使用很方便。

脚本使用的shell不是bash,而是expect。之前我们都是直接把一堆命令写在脚本里,但是如果遇到交互式的命令,比如ssh,telnet等就没有办法了,expect正是为了满足交互式命令的自动化处理。

在使用前,先需要安装tcl和expect,centos下,直接

sudo yum install tcl expect

也可以去官网下载压缩包,解压,然后编译安装。

下载完就可以使用了,具体expect的语法很丰富,网上也有很多文章讲的很详细。

对于ssh登录,我的简单三行脚本就搞定了。

!#/usr/bin/expect
set timeout 10
spawn ssh root@xx.xx.xx.xx -p xxxx
expect {
    "*password*" {send "ur password"}
}
interact

 spawn是我们需要执行的命令

 expect可以理解为接受远程服务器与我们交互所发送的信息,比如让我们输入password,在字符串前面加上-re,表示用正则匹配

 send则可以理解为发送需要的信息给远程服务器。

 interact执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远  程终端上。如果你只是登录过去执行一段命令就退出,可改为 expect eof

Tcp的那些事

看了皓叔的这篇文章,感觉总结的很好,非常适合收藏起来,做回顾复习用,于是再结合之前看《高性能linux服务器编程》这本书所了解的一些tcp知识,做一个归纳总结。

在tcp/ip协议族的四层模型中,tcp属于传输层,ip属于网络层。数据从上层到下层为封装,从下层到上层为分用。

ip负责路由,而tcp并不关心分片(数据包)的起点和终点,它只关心分片的下一跳(next hoop),通俗的说,分片就像快递,由北京到杭州,中间会经过许多快递点,而快递员只需要知道,快递的下一站在哪就行了。

一个tcp数据包的头部

Source Port表示来源端口,Destination Port标识上层应用所使用端口,例如常见的http->80, https->443,全部的端口号记录在/etc/protocols文件中。

Sequence Number是包的序号,后续该tcp链接的所有数据包传输,都需要以此序号为基础。

Acknowlegment Number,即为ACK,如果头部里含有该值,即表示对方已收到我们的数据

Flags表示包的类型,比如Flags是FIN,表示请求结束,PUSH表示发送数据,SYN初始化请求,握手截断

三次握手和四次挥手:这个无需多言,很重要。

关于四次挥手为什么是四次,这有段解释很通俗易懂:

假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说”我Client端没有数据要发给你了“,但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,”告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息“。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,”告诉Client端,好了,我这边数据发完了,准备好关闭连接了“。Client端收到FIN报文后,”就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,”就知道可以断开连接了“。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!

无论做什么,常怀敬畏之心

来自于一位大佬的总结:

国内的教程则喜欢把原本挺简单的东西给复杂化,把复杂的东西在装逼化、神秘化,就是给你一种“老子就是比你知道的多,就是比你们这群傻冒牛×”。这种怪现象值得每一个人思考,问题出在哪?!不会好好说人话,爱绕弯弯,让别人猜来猜去,稍微比别人多知道一丁点东西就喜欢高高在上的,以一种上帝教化民众的姿态训斥别人。我只知道闻道有先后,术业有专攻,你只不过比别人稍微早那么一段时间先知道了而已!也许在其他领域你还不如别人呢!请谦虚些,把姿态放低一些吧,生而为人,宇宙中渺小到微乎其微,谁敢说自己有资格(或者在哪些方面有资格)教育别人,请以一种相互探讨、有耐心、分享、平等的姿态说人话,不然称不上是程,只能算是一种炫耀。 
为他打call。
无论做什么,常怀敬畏之心!

空间索引-mongoDB

mongoDB提供了两种空间索引用来存储poi信息:

2d: 索引支持平台普通坐标的索引.

2dsphere: 可以对多种几何类型进行计算,包括点,线,面,多点,多面等。

使用示例:

  1. 创建空间索引:
    db.collection.createIndex({"filed_name":"2dsphere"});

    可以指定特定集合名称

  2. 插入GeoJson数据,mongoDB利用GeoJson Object来进行存储和计算。
    db.collection.insert({"location":{"type":"Point","coordinates":[40,5]},"name":"work poi"})
  3. 查询,mongodb提供了很丰富的查询操作符,各有用于,比如查找给定地点附近的点:
    db.geo.find({"location":{"$near":{"$geometry":{"type":"Point","coordinates":[40,5]},"$maxDistance":100,"$minDistance":0}}})

参考资料:http://www.cnblogs.com/zhenbianshu/p/6817569.html

https://docs.mongodb.com/manual/geospatial-queries/

读文章总结 – mysql那些事

原文链接:https://juejin.im/post/5a9b6342f265da23a2289281?utm_medium=be&utm_source=weixinqun

char&varchar
char是定长,对于超出长度的字符串,会截断,并且丢弃末尾的空格
char类型再数据变化的时候,会产生数据碎片(data_free)
varchar是变长,会有一个或者两个额外字节保存长度值

blob&text
即smallblob和smalltext,都是为了保存大数据的字符串类型

enum
保存在枚举类型字段里的值都是整型,.frm文件中会保存数字-字符串的映射

datetime&timestamp
分别是8个字节和4个字节,并且存储数据的格式都是yyyy-MM-dd HH:mm:ss‘
索引优化:
普通索引 : alter table a add INDEX index_name on column , create INDEX index_name on table_name(column)
唯一索引 : alter table a add UNIQUE INDEX index_name on column, create UNIQUE INDEX index_name on table_name(column)
全文索引 : alter table a add FULLTEXT index_name on column, create FULLTEXT idnex_name on table_name(column)
主键 : primary key
组合索引:遵循最左索引原则,即创建复合索引时应该将最常用(频率)作限制条件的列放在最左边,依次递减。示例:alter table table_name add INDEX index_name (column1, column2)

覆盖索引:指一个查询的结果从索引中即可获取到,而不用去查询表(回表操作),即select字段,where字段,orderby字段,groupby字段都在一个组合索引中,则该索引称为覆盖索引

传统意义上的索引就是指的B+树索引,这是目前关系型数据库系统中查找最为常用和有效的索引,其构造就是采用了二叉树的思想,根据键值对快速找到数据。通过B+树索引找到被查找数据行所在的页,然后数据库把页读入到内存,再在内存中进行查找,找到对应的数据。

对于Hash索引中的所有列,存储引擎都会为该列的每一行计算一个Hash码,Hash索引中存储的就是Hash码。

前缀索引和索引选择性:索引选择性是指某列的不重复索引值与总数的比值。计算:select distinct(column)/count(*) as selectivily from table_name
越接近于1,表示越需要
但是某些字段做联合索引,索引数据会十分庞大,可以使用字段值的一部分作为索引,alter table table_name add INDEX index_name (column1, column2(4))
查询资料:https://www.kancloud.cn/kancloud/theory-of-mysql-index/41849

Mysql查询过程:
1 mysql客户端发送一条sql语句给服务器,如果开启了查询缓存,那么服务器会去缓存里查找,(其实mysql判断缓存是否命中很简单,mysql会把sql语句,mysql版本,数据库名等综合因素生成一个hash值,并把查询结果放在一个引用表中与hash关联,如果当前的查询按照相同规则计算出来hash再引用表中关联,则命中)
2 找到缓存并且用户有权限那么返回缓存结果
3 没有找到分析语句,预处理,优化器优化并生成相应的执行计划
4 按照生成的执行计划调用存储引擎的api
5 将查询结果返回,并缓存起来
6 有些查询语句的结果不能被缓存,比如加入了SQL_NO_CACHE的语句,调用了某些系统/自定义函数,查询系统表(mysql、information_schema),LOCK TABLES READ/WRITE,SELECT FOR UPDATE等
查询资料: http://blog.csdn.net/desilting/article/details/9466629

优化数据访问:
优化数据访问的关键在于:减少数据访问量,只检索必要访问的数据,保证向数据库发出的查询数据量只是实际需要的数据量。
1 使用limit
2 尽量减少select *的使用
3 缓存结果
4 如果需要扫描大量数据,但只需要少量数据,使用覆盖索引减少磁盘的io

重构查询:
1 分解查询
2 优化关联查询的顺序
3 分页页数过多,使用联表和覆盖索引来加速查询
查询资料:http://blog.csdn.net/yejr/article/details/70039403