好吧,本日又双��要提小密圈,不外这次真的不是为了拉粉,而是由于刚好这个场景,在技能计划上很典范。
小密圈春节后发作很快,那么技能上就碰着了一些瓶颈和题目,吴总就拉了几个好伴侣做技能参谋,帮他们照料一下,有幸我就成了个中之一。
先处理赏罚了两个数据库慢查询的题目,证明白我对数据库的索引领略依然还能用的上,不外这不是什么关键题目,由于体系负载和瓶颈不在这里。
那么,在对方的共同下,我们就对措施负载做了抽样的说明,并将一些执行开销略大的剧本负载,通过机能说明器材做了一下拆解,然后留意到,绝大部门开销较大的哀求,是用户进入特定圈子首页的剧本,而这里开销最大的部门,是内存的频仍哀求。限于信息安详的思量,对过于细节的技能描写,很歉仄,我不会睁开,我只基于这个案例,睁开说一下关于较量常见的计划思绪误区,和一些计划的思索要领。
通过这个案例我意识到一个征象,着实许多小创业公司都也许碰着的征象,一些技强职员,对体系开销的领略不足彻底,不足踏实,会有一些简朴的标签化思想,好比说,数据库每每是机能负载的瓶颈,而行使内存数据存储,可以避开数据库的瓶颈,从而实现机能和相应手段的晋升。
这个设法,不能说是错的,由于我们碰着数据库瓶颈的时辰,也是通过内存数据存储来优化的,但不能简朴化这个题目。并不是说,全部场所,内存存储都比数据库更良好。
早年我举过一个我们本身的案例,我们存储用户session的时辰,用了mysql 的heap范例数据表,这是内存表,这个表的存取频率是极高的,但由于写入过于频仍,功效,锁表严峻,常常卡死,导致体系因数据库守候被整个卡掉,虽然,这可以以为是一个履历不敷的菜鸟题目,功效换为innodb,行级锁,题目就办理了。 那么,从内存表换成物理表,看上去是机能降落的,但由于行级锁比表级锁更靠得住,在频仍写入的环境下,假如i/o撑得住(请留意这个条件哦),那么现实上靠得住性是更优的。
那么返来说,相关型数据库,我们常用的数据库布局,其索引范例,差不多是btree相干的,详细呢,我也不是很能干,在索引优化到位的环境下呢,其查询服从呢,趋近于log2(N)。而一些内存表布局,哈希索引,其查询服从,凡是趋近于1,也就是寻址搜索,这个针对你明晰的key- value查询,绝对是有上风的,(虽然,按照一些信息安详测试的披露,在非凡环境下,也许查询服从会直线降落,但这个不是本日要评论的重点,就列在这里,以免有人挑错。)
但这里有两个延长题目
题目1:哈希索引只合用于key - value这样的简朴查询,而相关型数据库可以得当较多的前提查询。 也就是哈希索引现实上合用空间是极为有限的。并且也不支持排序等操纵。
题目2:并不是全部内存数据表布局都是哈希索引,好比前面提到的mysql 的heap表布局,着实也是相关型数据库,btree范例的索引。那么另一个出格要提到的,是redis有个常见布局,有序荟萃,由于这个布局支持排序,支持快速的排名统计,以是应用领域也很广,可是要出格声名,这个表布局,存取的开销是宏大于哈希布局的。
有序荟萃有一个极佳的更换相关型数据库的应用场景,就是积分排名的场景,早年技能大牛云风提到过一个经典案例,某友商的游戏,积分排名挂死数据库,这是很常见的一个题目。
一样平常行使数据库做积分排名,任意写一个,懂SQL的都能看懂。 select count(*) from gamepoints where points>$mypoints 。获得的统计数据+1,就是我的排名。但这个SQL的开销怎么计较,这是一个很经典的数据库负载测试题,在你行使points作为索引的条件下,其负载开销与你的排名线型相干,也就是,你要是排名靠前,负载险些可以忽略,你要是排名靠后,负载直线上升。无论任何数据引擎,无论myisam,照旧innodb,无论mysql照旧sql server。假如不动技能架构,不改产物计划,纯SQL优化,两个字,没戏。
这个场景,行使redis 的zrank来处理赏罚,爽爽的办理,毫无压力。这是这个布局最有代价的处所。但统统都是有前提的,其插入,更新,编削的体系开销,要远高于redis的其他数据布局。 而其代价,仅仅在这个场所,是具有绝对上风的。
说了这些铺垫,回到本日的场景,小密圈的圈子首页,毕竟出了什么题目。
小密圈的研发,我预计是对数据库的行使不足自信,大量行使了内存来做数据存储和加载,并且,为了一些排序的需求,还大量行使的是有序荟萃范例,真话说,这样的内存处理赏罚,跟数据库处理赏罚,就同样的哀求而言,机能上已经根基没有上风了。
但题目还不在这里,而是他们也许没故意识到,哀求频次的题目。
打开一个小密圈的首页,先去内存读取这个圈子最新的帖子,这是一个常见的哀求,可以领略;然后就可骇了,基于每个帖子轮回,去查询该帖全部的评述,全部的赞,全部的赞赏,全部的文件,全部的图片;然后,基于每个评述,再去查询相干的图片,文件。。。
简朴说就是,打开一个页面,要举办几十次以致上百次的内存查询哀求,而这些开销,用我的领略,是毫有时义的。
假如我写数据库查询,第一条SQL查询帖子,后头的用 where postid in (...),最多四条SQL (查询评述,查询附件,查询图片) 即可。 这种轮回体内的一再查询,长短常要不得的,其体系负载开销是无谓的,毫无代价的。
那么,这里袒露的题目是什么呢?着实,体系计划的时辰,应该有一个根基观念,就是怎样尽也许镌汰不须要的哀求,镌汰无谓的开销。用数据库也好,用内存也好,并无绝对对错之分,但应该基于一个原则,就是怎样让体系更有服从的运行。
早年许多措施员面向工具编程,常常不留意这些开销和细节,用数据库查询,也常常有相同的题目,好比说,我读取一个图书列表,先通过某个搜索前提去搜索出全部图书id,按理说到这一步已经足够了,但由于面向工具啊,通过图书id去得到图书的名字,作者名字,页数,简介,是工具里的一个要领,然后就酿成一个轮回内不绝去数据库哀求,其拭魅这些哀求都是毫有时义的,第一个查询完全可以所有获取,一一哀求完满是多余的,但这样的案例不可胜数,险些每次带技能新人,城市犯一遍这样的错误。

回到上面的题目,什么时辰用内存,什么时辰用数据库,我们对用内存的场所,是有一些本身的原则的。
第一,内存行使,是基于你的营业场景,而不是基于数据布局。
这是什么观念呢,内存是为了提速的对差池,是为了低落负载的对差池,以是内存的计划,是基于我营业场景的哀求诉求计划,而不是把内存当数据库用。
人工智能如何让SEM营销落地
4月25号百度的SEM营销中国行会议在北京国贸大酒店举行,会议主题是:营销之道,因智而能。 这两天相关报道几乎是刷屏般的存在,会议内容中出现的人工智能,智能











