以后代码都放这里了LeetCode_Solutions
MySQL学习
首先推荐三篇文章:
1.MySQL索引背后的数据结构及算法原理
总体概括了MySQL内部的索引原理及索引使用策略
2.剖析Mysql的InnoDB索引
侧重剖析了InnoDB的Page结构,更加详细的见Jeremy Cole的博客
3.Judy的B树
侧重数据结构的分析,注意只是数据结构。。
此外还有官方的InnoDB文档
总结重要的内容如下:
1. 使用B+的原因,相对于红黑树等二叉查找树,树的高度低,能减少IO次数。相对于B-树,稳定,更利于范围查询。相对于Hash表,更利于范围查询,伸缩性更好(在无法预知表中记录数时),详细见这里的讨论
2. InnoDB与MyISAM索引实现的区别,聚集索引和非聚集索引的区别
3. 建索引时的最左前缀原理,数据库表的主键选择
4. 慢查询日志及explain关键字
GitHub浅探
学习The-Art-Of-Programming-By-July,感觉写的不错,突然想看下github上比较流行的Repositories
可以在这里,对github上的资源进行自定义搜索,这里(貌似需要翻墙.手动汗..)也有比较新的总体的统计
截止当前,有以下结论:
1.star数大于10000的项目有354个, 其中JavaScript的项目占了127个。。
2.按组织来查看,前16名如下:
其中的第三四名。。我也不太懂。
取前16,只是因为第16名。。其他的有
三大组织在排名上,还有一些分支,大家可以自行查看
个人分析:
一.JavaScript项目较多,可能因为
1.在web上,后端有多种语言实现,而前端的业务逻辑实现主要使用JavaScript
2.node及相关项目也被归到了JavaScript
3.前段JavaScript由浏览器执行,相对难以加密
4.JavaScript相对于后端代码库,更容易集成到项目中
二.国内公司的开源力度(技术水平?),相比国际顶尖公司,还是有些差距
三.教程类项目容易获得高star,比如free-programming-books,awesome,google-interview-university…内容也的确不错。。
"MySQL server has gone away"
一个很久没有运行的后台服务,在接收到数据,运行时,报了这个错误
原因是服务用的Django ORM与mysql在长久没有数据交互后,它们之间的长连接断掉了。
以下分析基于django1.6.0
Djando自带的ORM是比较定制化的,在django处理一个web请求时,在请求开始时,和请求处理完成时,Django都会尝试关闭数据库连接,如下代码所示:
不过,根据close_if_unusable_or_obsolete的定义,除了自动提交和发生错误两种情况外,连接是否确定关闭,还取决于close_at的值,
self.close_at会在连接时改变:
所以,具体到每个请求是否关闭连接,还取决于CONN_MAX_AGE的配置,而CONN_MAX_AGE的默认值是0,所以默认情况下,每次处理完毕web请求时,都会关闭数据库连接。
另外一个很重要的一点是,Django中,存储数据库连接的字典是基于线程的:
所以,如果你的web服务器的网络架构是多线程或者多进程的,即使设置CONN_MAX_AGE不为0,也不会复用旧的数据库连接,在这种情况下,如果数据库是mysql,因为Django orm不再会主动关闭数据库连接,mysql服务器会根据wait_timeout的设置,一直等待着,这种情况下,很有可能,造成mysql连接数过多,反而适得其反。
如果web服务器是单线程或者协程的,例如我测试用的gunicorn+gevents,适当的设置CONN_MAX_AGE,则会复用数据库连接,提升性能。
回到我们遇到的错误。。
我们的服务只用到了Django的ORM,所以在web请求开始和关闭时,django对数据库连接的尝试关闭对于我们的情况完全无效,服务又是一直跑着的单进程单线程,所以,在服务启动时,直到终止,会一直只用同一个数据库连接,长时间的服务不连接数据库,mysql会根据wait_timeout的设置,关闭了连接,所以也就导致了2006,’MySQL server has gone away’错误。
之前,使用tornado提供web服务,而使用Django的ORM时,也遇到过这样的错误,原理一样。
解决方法有:
1.增加mysql中wait_timeout的值,但这有一定的风险,而且不能从根本上解决问题。
2.同Django中的做法,在不需要数据库连接时或者开始数据库操作前,尝试关闭数据库连接。
3.自己DIY了一个变量CONN_WAIT_AGE,同时修改代码如下:
修改函数,增加:
修改函数,增加:
修改函数为:
CONN_WAIT_AGE需要设置为比wait_timeout小的值,不设置为不启用。
安装GitBook小记
看小程序文档时,发现文档是使用gitbook生成的,很喜欢这种风格的页面,于是尝试着在自己的服务器上也搭建一个。
从这里,首先在服务器上安装npm,使用命令yum install npm,能找到安装包,可是总在安装过程中被莫名杀死。
于是尝试着下载nodejs安装包,编译安装,同样报错被杀死然后尝试下载编译好的程序,解压时报错
终于发现是服务器的内存问题。。
可用内存不足100MB
然后发现23个php-fpm进程占据了将近70%的内存。
我是使用的阿里云的云服务器,内存只买了1G的,包括这个wordpress博客,mysql数据库,一些自己弄着玩的程序都跑在这台服务器上。php-fpm使用的是默认的配置,结果造成内存使用率过高。
而实际上,我的博客的访问量并不算大(可以说很小。),于是,更改php-fpm配置,降低其工作进程数,重启后然后使用yum install npm,终于安装了npm..
接下来按部就班。。
请见第一个book
Web性能压力测试
用ApacheBench进行网站压力测试
原理:ab命令会创建很多的并发访问线程,模拟多个访问者同时对某一URL地址进行访问。
使用方式网上有很多,主要参数是-n(请求总数,设为参数n)和-c(并发数,创建的线程数, 设为参数c)
结果分析:
Concurrency Level: 即参数c
Time taken for tests: 整个测试持续的时间, 设为参数t
Total transferred: 整个测试过程网络数据传输量,设为b
Requests per second(mean): 即n/t
Time per request(mean): 即t/(n/c)
Time per request(mean, across all concurrent requests): 即t/n
Transfer rate: 即b/t
根据我的使用经验,需要注意的是:
1.这个只是服务器性能测试,并不能测试网络状况。也因此,测试机网络状况需要足够好,相对于服务器的带宽要足够高(大于Transfer rate)
2.因为是固定URL, 可能有时测试并不能反映实际情况
3.根据需求,可以做集群压测,或者是单机压测
从ftp服务器上下载文件或文件夹
`
def download_paths(ftp_object, path, destination):
“””
从ftp服务器上下载文件或文件夹
:param ftp_object: 一个已连接的ftplib.FTP对象
:param path: ftp上的路径
:param destination: 本地文件夹
“””
to_path = os.path.join(destination, os.path.basename(path))
file_list = ftp_object.nlst(path)
if len(file_list) == 1 and file_list[0] == path: # 如果是文件
ftp_object.retrbinary("RETR " + path, open(to_path, "wb").write)
elif len(file_list) > 0:
if not os.path.exists(to_path):
os.makedirs(to_path)
for f in file_list:
download_paths(ftp_object, f, to_path)
`
Django中的索引和约束
1.db_index控制单个field是否要创建索引
2.如果field是外键类型,则db_constraint控制是否有外键约束
3.如果是外键类型,默认会创建索引和约束
4.unique_together和index_together控制创建联合索引,在mysql中,联合索引中field的顺序会对部分查询产生影响
我对Web后台的一些看法
1. qps, 曾今分析过公司的Nginx日志,单台应用服务器的日访问量大约等于30000峰值qps,而我们web服务的单日访问最高达8亿,如此算来,我们web服务的峰值qps也有25000以上,当然,实际到达后端web应用的访问应该不到其1/4,这些访问又会分发到不同的服务器上。具体到每台服务器,假设每个请求耗费10msCPU时间,单台服务器是16核,完美情况下单台服务器能处理的最高qps也就是10016=1600。
2. 服务器抗压分析,首先当然是数据库,处理一个请求时,业务逻辑上的处理,可以通过增加服务器来解决,但是通常为了数据的一致性,数据都存在一个数据库中,高并发时,数据库的访问压力会比较大,解决方案通常是优化业务代码,减少数据库访问,对数据库建立适当的索引,数据库主从甚至多主,使用缓存。如果业务逻辑比较复杂,处理一个请求的时间相对较长,可以考虑使用消息队列,专门一组机器处理后台逻辑。如果后台处理时,IO操作比较多,后台web服务器的网络架构最好选择事件驱动模式或混合模式。根据业务,可以分组服务器。静态文件可以使用CDN等。
3. 页面加载速度,首先是从客户端发出请求,到收到所有数据,这个过程就像在客户端和服务器之间架有一条管道,首先一部分水从客户端流向服务器,之后服务器返回响应水流。管道的长度,BGP多线,CDN的存在,就是为了缩短管道的长度。从服务器端收到请求,到服务器开始返回响应,可尽量降低后台处理请求的时间(后端缓存,异步处理数据等)。服务器响应数据的大小,假设用户使用移动3G网络,网速为100KB/s,如果一个页面的数据(包括js,css,图片)是400KB(电脑版baidu首页的级别),只是下载数据就至少需要4s(排除客户端缓存)。前端优化可见这里。