自己原文公众号:
https://mp.weixin.qq.com/s/o7HjQwEVcbkWUkG6Hzlwsw
首先这个篇技术贴。前面先铺垫一下,最近苏伊士运河的各种新闻。
我以前读中东战争时候不理解为什么有一次叫苏伊士运河战争,也不明白为什么要争夺西奈半岛和戈兰高地。这次算是彻底明白了。看到上面的图,苏伊士运河是咽喉要道,而半岛和高地直接控制这片区域。
本文起因是系统的瓶颈是什么?一般来说瓶颈都在数据库,数据库瓶颈都在IO。如果让数据库拜托IO,即我们都读内存。会是如何?
基于以上我分几天来说,今天是MySQL篇,后面再有Oracle和PG。水平有限就自己假设了。我们模拟一下登录,有不少人担心系统登录是瓶颈。其实不然。看看我们实验。
create table user ( id int auto_increment,userid varchar(10),password varchar(10), primary key(id)) ;用户表
create table qx (id int,userid varchar(10),qx varchar(10));权限表
这里是关键,为什么?因为一般开发设计的权限表特别复杂,效率不高。我这里是理想化的设计,为了看看最快如何?
我见过别人设计的一登陆查菜单,也不管用不用得到。菜单是级联的。10个父菜单,每个父菜单都有10个子菜单,然后才来一级。所以一登陆就1000个SQL。实在不知道那家公司的是怎么设计的,什么脑回路。
这种一般都会对我说:
1、这是我们产品就这样设计的
2、我们代码底层是这样设计的
3、框架就这样设计的。
总之一句话,让我改是不可能的。
所以这里(设计)就是苏伊士运河,所有的问题我发现几乎都来自设计或者实现。
数据库是苏伊士湾,虽然比起来外面的大海不具备可扩展性,但是处理这些还是绰绰有余的,不是每个国家(公司)都是有十几个航母编队,几千战舰去把苏伊士湾(数据库承受能力以外)堵死的。
如果这两个都解决不了,外面的星辰大海(地中海和红海),就算你能扩展又如何?
create procedure 模拟50万用户,然后我们再写一个存储过程去读这些数据。
DELIMITER //
CREATE PROCEDURE us()
BEGIN
DECLARE v int;
SET v = 0;
loop_label: LOOP
insert into user (userid,password) values ( concat('t',v),v);
SET v = v + 1;
IF v>=500000 THEN
LEAVE loop_label;
END IF;
end loop;
END; //
其实数据库的读能力很强的,前几天腾讯金融的姜老师发的MySQL每秒120 万次QPS,那是用官方的压测工具测试的,机器CPU也多。全部满负荷的。
我们今天来试试单CPU的。
BEGIN
DECLARE v int;
DECLARE a varchar(10);
DECLARE b varchar(10);
DECLARE c varchar(10);
DECLARE d varchar(10);
SET v = 0;
loop_label: LOOP
select userid,password into a,b from user where userid=concat('t',v);
select userid,password into c,f from qx where userid=concat('t',v);
SET v = v + 1;
IF v>=500000 THEN
LEAVE loop_label;
END IF;
end loop;
END
仅仅表示拿到用户名 密码和权限。这是登录最简单的场景。如果你设计了登录以后还有很多操作要做,那你势必影响登录效率。看看淘宝 京东 微博 登录都是比较简单的页面,没有后台实时计算什么的。
我一直认为登录就应该是简单的,不应该有压力。因为查询是所有数据库中操作最轻的。
如果你登录都担心,那就不担心登录以后的浏览和下单吗?那些操作才是真正的压力。
单线程CPU全满的效果是每秒1万。50万全部执行完毕大约50秒,平均每秒读1万次。
开了3个以后那么3个CPU满负荷也就是 说3个每秒1万的登录是可以的。那么我们得到一个理想化的结论,在设计简化的前提下,承载能力是每秒每个CPU可以处理1万次请求。充分利用数据库多线程。
