干货|建议初创团队起初也要构建分布式应用

本文内容整理自W-Time技术分享沙龙-天津站现场演讲《一切都是分布的》,演讲者:李傲,问啊联合创始人,前中交车联网总架构。

好多人都会问什么是架构师?其实架构师的定义很宽泛,前端后端的定义都不一样。作为后端出身的架构师,我认为后端并不是大家想的封装组件,它要定义的是规划,规划模块之前的关系。在一台机器搞不定时怎么办?答:集群!这词说着很容易,但真要给你,你发现how?怎么去加?

有人问我,架构师要做什么?我认为,架构师就是要在软件起初阶段就能够从情景当中预先想到这问题,通过架构分布式解决方案,预先把问题都埋好。可能有人会说这算不算重度设计?其实所谓重度设计,要看团队的基本能力,如果团队写代码还写不利索的情况下,那么这个设计就很重要。因为不能指望一个代码都没有写过几行的人去写架构,这个是不可能的,做分布式都很难。如果团队能力属于中上层,那么有两种可能:1、团队做过十几年的代码,但架构差一些,那么也会把程序写的非常漂亮,因为对代码有把控能力,对底层的研究比较透彻;2、代码写的并不是很好,但是架构师对新技术有了解,那么也是有可能做好分布式的。如果你的团队做不到以上这些,那只有一种方法——用服务器抗。但服务器是一回事,团队能力也不能太差。

下面就我们“问啊”来说给大家做一下简单的分享,“问啊”是一款订制化IT教育平台,可以一键呼叫大牛解决IT 问题。

关于分布式存储

“问啊”利用了一些分布式的概念,也就是分布式存储。我们都知道,每一台服务器资源占用都是有限的,我们用的是云服务器,一般上来都会去买本地磁盘,但无论容量多大,总有一天会用完,当这一天到来的时候,有两种可能:1、在你不知道的时候,服务死了,怎么也起不来。可能会不运行、cpu过高,有人会问,这什么原因导致的?计算量太大了?其实不是,因为一直在做无谓的io操作;2、无从下手,有个公司叫emc的做的磁盘可以解决,可是太贵,300万左右的价格初创公司老板肯定不批,而且性能也不能保证。

但是分布式存储就把这个事解决了,将要存储的文件预先就散出去,而不是放在一个地方。拿的时候就很快的知道在哪了。举个例子,就像大家都有房子,每个房子都有地址,这个地址都是预先规划好的,就跟分布式存储一样,在规划的时候就解决了未来如果数据膨胀会怎么样的问题。

关于高速缓存

接下来再说高速缓存,这也是一个分布式缓存的概念,对存储和缓存来讲,在算法的选择上是不一样的,数据分为两种,维度数据和事实数据。维度数据可以理解为是一种属性,人也是一种维度数据,这个数据是有尽头的。事实数据就是我出门的时候可能会踩死一只蚂蚁,但我不知道我这一路会踩死多少只,这就是事实数据。包括广大的女性同胞养活了淘宝,这也是最好的例子,都是事实数据。

事实数据存储和维度数据是不一样的,大家一般按时间存储是最多的,这样数据在取得时候有一些优势——可以单独拿一段出来。在数据结构中,拿一段怎么拿?肯定得是连续存储,这样对cpu的消耗则是最小的。那维度数据呢,数据量本身就不大,我们用hash是比较靠谱的。

对于内存和磁盘的存储来讲,磁盘是一个盘片,我们在寻找一个道的时候,我们会连续去打,这样是最快的。因为不会跳针,跳针速度是最慢的。但内存不是,内存是随机存储,我们在利用存储的时候也会考虑到,如果对于连续存储来讲,内存就一定比磁盘快吗?在我看来,不一定。

关于任务队列

我之前做车联网,包括现在的滴滴打车都是一样的,大家之所以能打到车,是车的位置信息已经上传上来了。因为在同一时间内会爆发很多小高峰,导致我存数据的时候很慢,所以我不直接存储,我先存到另一层去。为什么要存到另一层呢?我们存储的目的就是为了要拿出来,简单的说:存的目的就是拿。其实存和拿是一个悖论,好存不好拿,好拿不好存。举一个例子,这么说可能可以直观一些。上大学时,放学回宿舍,书包就扔在地上。为什么?因为懒,扔的速度特别快,但是你可能转天再找就找不到了。问题就出在存储快但是没有索引。想要快速查到怎么办?那就在存的时候分门别类,细致存好。这样拿比较快,存的时候就会费一些时间。如何解决这个悖论?读写分离。存和查的时候一定要做分离。软件有一个理论叫“解偶”,如何解偶?简单来说,a层和b层之间加一个c层就是解偶。只要你发现两层之间有一个很紧密的联系,你就往里面加一个。

所以,任务队列就是这样,我们先把东西写到队列里,让它慢慢的去消费。也就是说你把数据拿到队列里面来的时候,我就认为你存了。等你取得时候,看你的消费水平,消费水平慢,最多就一个感觉:这个更新好慢,仅此而已。然后下一步就该研究怎么把这个消费做快,你是有这个机会的。但如果你这个事儿不这么做,你就会发现,在你存的时候就已经死了。这样用户的感受可能会有两种,一个是用户并不知道,他只会觉得你们公司的数据比较少;二是我知道,你们已经死了。这样的用户体验度是非常不好的。

关于高速查询

这里我要讲一下我们查询的数据结构。对于每种查询来说,数据结构都不太一样。现在有一种比较好的既能查又能存的数据结构叫LSM-TREE,就是hbase一个数据结构,大家有兴趣可以看一下。

如果你是一个应用,你可能会发现其实没有现成的东西可以用,怎么办?那就用最短的时间研发出来一个轻量级的分布式,像任务下发。这种东西其实比较占资源,当你的服务器数量不够庞大,节点数量也不够庞大的时候,你拿到的结果可能跟你最初的预想不太一样。

互联网公司都有个比较难受的事儿,就是做运维不敢动机器。我们在做“问啊”的时候也没有完全做到不停机,这个挺难的。有的时候为了尝试试错,我们需要做降级指标,其实有时候比升级指标难的多,会丢数据、丢节点,之后数据还能够均摊,这个是挺难的。我们现在降级指标还没有做到完全不停机,但升级指标已经能够做到了。其实这就是各种负载均衡,通过负载均衡来代替ha,那么这两个概念是什么概念呢?ha,高可用。负载均衡,就是就是你一个人搞不定,四五个人一起上!ha是什么?一个活着,另一个就得死。一般用负载均衡来解决高可用有个问题,就是机器不闲着。一般来讲,做机器空闲的话,总有一台机器是不干活的,这个对于初创公司来说成本比较高,配置选择就是个难题。所以各种ha方案一般就是共用,那个节点可能会分摊好多个节点的共用,但是突然间发现两个小高峰,两个死了这个也就算死了。对于loadbalance本身有个非常大的优势,就是本身来讲,只要有1/2以上活了,这服务也就认为是活的,这个是比较好保证的。但是有一点,做lb算法就一定要做到线上的配额一定要高于你目前的配额,否则你是没法做的。

下面分享一下我们用过得一些东西:

Redis

一个基于内存的存储。最大优势就是单线程处理的。肯定有人问为什么做单线程,很慢的!但是如果你测过的话就会发现,单线程多任务有时候不一定就比多线程多任务慢,多线程多任务有个空闲的概念,交替的概念,我要去调度。这个就完全省去调度,只要存储速度特别快,能让一个线程别空闲了,远比多线程多任务要快。单线程有一个不可替代的优势:无锁,可以做到一致性。多线程本身来讲只要并发对一个数据操作的时候,你就必须得加锁。你的锁如果设计不合理的话,你这个数据本来可以加到5的,结果才加到2就没了。

如果用redis完全不用考虑这些事。包括我们做订单号的话,单号取一个数,这是个最普通业务。我们对单号+1就会考虑一个线程去做,如果可以搞定的话,那速度就快了,那我为什么要去做多线程?那么做多线程有一个方法,你可以先把订单号切割,就是预计今年的订单号能有多少,你先把他分好了。然后每一个进程怎么样操作,这样不会出问题。但是订单是跳跃,永远不要用订单号去做排序,这是最不合理的。就像大家都玩过摇红包,其实都是一样的,摇红包为什么能做到这么快。其实不可能快,这个事情不是一个快的动作,有交互就不可能快。只能先把交互的红包预先切好了,存在缓存里。甚至最狠的是用一些空池,就是没奖。结果你的ip正好打到这一核了,hash到这一核里。不换ip拿不出来。

Redis本身来讲,它的存储速度包括查询速度是可以上到10万级的,是非常快的。但是我们线上测的话。可能也是因为我们用的是云平台的一个服务,它本身是基于codis做的分布式服务。我们没有时间去做自己的分布式redis,所以codis已经成为我们的瓶颈了。它大概的速度也就是1w,对于刚起步的应用来说应该够用,那如何做到更快,只有一个方法:当你对一个事儿做到不能更快了,就三个字解决:分布式。这样就肯定能解决,下一步再去琢磨这一个事该怎么解决,这个就更高深了,有机会我会再详细的为大家讲解。

Hbase

有人说Hbase是大数据,其实我觉得很诧异,我认为大数据更偏重于分析。这个东西本身就是一个nosql ,为什么要放到大数据呢?也许因为存的数据多?

一开始起步的时候是三个节点,这算大数据吗?这算是实验。其实不是,它就是一个数据库,大家不要对它有偏见,认为非要数据到多少的时候我把它迁过来,记住,数据量大的那天,你再想迁就迁不过来了。我的经验告诉我,重构可以做局部模块重构,但绝对不能做大迁移。只要做大迁移:丢数据、版本核对,动态版本核对,特别头疼。

我最怕跳槽,因为我的位置是救火的。经验告诉我这个最好提前设计好。因为到那天了你难受,有两方都不满意:第一,用户那里,一直在用,你就得天天看着,怎么还有用户用?不知道该用高兴还是该不用高兴;第二,产品经理、运营就会使劲催你问你好了吗?但是提前规划好,就可以避开这些问题。

Hbase本身来讲呢,既然它能存这么多数据,我们也不想太浪费。有两套出报表的方案,一套是大家熟知的spark,可能用的比较多。对于一个初创团队来讲,spake本身它的worker节点配置有点高,因为它专门吃内存的。还有一种。Tkeyang24:06,替代hadoop,但是它本身没有计算模块,你还是上s,逃不过去。我们的方案呢,作为一个初创团队来讲,对于运营这一块可能有点残忍,但是没有办法,没有这么大的数据量,没有必要。

那么插入数据方案呢,就两个:

1、通过集成phoenix序列化方法使用原生Hbase API插入更新数据,数据装载速率并没有降低;

2、插入数据时采用双保证,缓存和hbase均需要完全插入成功,否则记录日志进入修复队列异步保证数据同步。

高速缓存

关于高速缓存,刚刚有说过, redis最好的方案就是hash。这里说两个应用,Redis本身有个pub/sub,做数据队列的,并列时队列比较麻烦的是,如果想用它做一对一队列,你是做不了的,其实一对一有很多队列。但是作为初创团队没必要,那如何来解决这个问题呢?很简单。我们分布式里,分三个redis,我这一个应用先用三个redis,写数据的时候我在三个里面做shard,你这一个应用shard这三个,那这一个应用就可以把这三个归过来我用,如果两个应用怎么办?有两种方法,一种方法从k上,我监控不同的shard的队列,a监控a队列,b监控b队列,每个人都监控三个,没问题,但还有一个问题,redis本身来讲,提供一个key失效的概念,缓存一定会有时效时间,但是缓存失效之后,他所定义的队列的名字是写死的。是跟十六库绑定的,我们可以切16个作为拓展。如果十六不够的话,切两组作为拓展,这样的话就可以无限的扩大。B监听b的零号库。这样可以无限的扩大这样可以通过阔机器,来提升一个人的消费能力。另一方面通过纵深,来分散消费能力。

关于Redis2.8.22,可能用的比较多。3.0和3.2用的并不多。这有个毛病,TTL只要move一次库,这个TTL就废了,就是失效时间。本来是想用什么巧妙的方法来做黑科技的,结果发现2.8.23解决了,所以大家用的时候从2.8.23以上用。

我们在任务队列主要做的事是,我们应用有个红包的概念,为了让大家都有学习的机会,能够去问问题,所以我们有个红包。如果用分布式的话,会有很多坑就可以绕过去了。

Pub/sub,有一个比较恶心的事,当你消费的时候,如果消费函数,你没有消费下一条的时候,pub/sub是不往后挪数据的,所以他会大量的堆积在redis里出不来,这个一定要注意。

我推荐一个工具,现在有不少公司都在用这个:ES。这个还是比较好用的,但是现在有个问题:随机函数。它里面可以随机抽量数据,在随机抽量数据的时候我们发现两个坑,1、散不开,大部分都一样,随机不太好;2、随机速度特别慢,100w就开始特别慢了。做抽量的话,其实还有很多可以试一下。

关于我们自主研发的,主要就是以下这几点:1、针对服务节点运行数据决定任务的下发;2、任务之间没有任何牵扯;3、任务死亡可以实时分裂新任务继续执行;4、支持定时消息及红包的应用。

我发现很多人有个误区,不写代码就真的省事吗?我觉得吧,不写代码满足需求最省事,用现成的有时候还不如自己写,有什么问题也好找。

关于不停机运维

Zookeeper这个东西挺好的。我现在注册一些服务,立刻就会建上临时的链接,临时文件。比较坑人的地方就是它的存储是限量的。每个节点存储都一样。一定要注意,存储要省着使用,别写进数据,不要用它做分布式事务所。Zabbix挺好用的,我们运维现在就使用这个。

时间: 2024-10-10 07:56:24

干货|建议初创团队起初也要构建分布式应用的相关文章

初创团队的技术选择

初创团队的技术选择 良好的技术选型,能最大程度地提高初创团队的效率,从而开发出满足需求和用户体验的产品.正如诗中所说"马烦人怠当劲虏,虽持利器安得强".技术选型应以选择团队最熟悉的技术为唯一原则. 1.选最熟悉的技术 什么是团队最熟悉?这要看当初组建团队时团队核心成员所掌握的技术技能,初创和作坊团队应当以这些核心成员的技术为主,避免用得过于驳杂. 如果只能选择某种技术路线,比如团队只会PHP技术,也能满足业务需要,暂时似乎没有别的更好的办法,只能将就一下了. 有人会认为这种原则毫无远见

【面试】吃透了这些Redis知识点,面试官一定觉得你很NB(干货 | 建议珍藏)

原文:[面试]吃透了这些Redis知识点,面试官一定觉得你很NB(干货 | 建议珍藏) 万字长文,干货满满. 是数据结构而非类型 很多文章都会说,redis支持5种常用的数据类型,这其实是存在很大的歧义.redis里存的都是二进制数据,其实就是字节数组(byte[]),这些字节数据是没有数据类型的,只有把它们按照合理的格式解码后,可以变成一个字符串,整数或对象,此时才具有数据类型. 这一点必须要记住.所以任何东西只要能转化成字节数组(byte[])的,都可以存到redis里.管你是字符串.数字.

纯干货!华为软件开发云编译构建之Maven

一.Maven介绍 Maven是一个项目管理和整合的工具.Maven为开发者提供了一套完整的构建生命周期框架.开发团队基本不用花多少时间就能自动完成工程的基础构建配置,因为Maven使用了一个标准的目录结构和一个默认的构建生命周期. 二.Maven用途 Maven提供了帮助管理 构建.文档.报告.依赖.SCMs.发布.分发的方法.可以方便的编译代码.进行依赖管理.管理二进制库等等.Maven的好处在于可以将项目过程规范化.自动化.高效化以及强大的可扩展性利用Maven自身及其插件还可以获得代码检

初创团队持续集成的落地与实现(gitlab+python)

持续集成概念 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成.每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误. --马丁福勒 git工作分支 持续集成的前提必须要有一个健壮且分明的版本工具,毫无疑问我们这里使用git作为版本工具 这里只简单说一下各个分支的作用,想了解更多关于git工作流知识,请点击深入理解学习Git工作流 feature/* 功能分支,用于一个新的功能的开发 h

干货好文!自底向上——知识图谱构建技术初探

知识图谱的构建技术主要有自顶向下和自底向上两种.其中自顶向下构建是指借助百科类网站等结构化数据源,从高质量数据中提取本体和模式信息,加入到知识库里.而自底向上构建,则是借助一定的技术手段,从公开采集的数据中提取出资源模式,选择其中置信度较高的信息,加入到知识库中. 在本文中,笔者主要想分享一下自底向上构建知识图谱的全过程,抛砖引玉,欢迎大家交流. “The world is not made of strings , but is made of things.” ——辛格博士,from Goo

为何这篇RxHttp Http请求框架会如此销魂,全文干货建议收藏!

前言 RxHttp相较于retrofit,功能上,两者均能实现,并无多大差异,更多的差异体现功能的使用上,也就是易用性,如对文件上传/下载/进度监听的操作上,RxHttp用及简的API,可以说碾压retrofit:另外在baseUrl.公共参数/请求头.请求加解密等功能上的易用性都要优于retrofit:然而这些,个人觉得都不算什么,个人觉得RxHttp最大的优势在于它近乎为0的上手成本.极简的API以及高扩展性,看完这篇文章,相信你会有同感. 那RxHttp就没有缺点吗?有,那就是它的稳定性目

初创团队管理

团队的确不好带,越是资源匮乏的小企业,团队的组建.稳定和凝聚,难度就越大. 在小企业,团队成员的价值观一致非常重要. 只有价值观一致的团队才会有默契:只有价值观一致的团队才经得起外界的诱惑:只有价值观一致的团队才能共同面对风雨,不离不弃. 在小企业里,招一个人进来,让一个人离开,对团队引起的或明或暗的振荡都不容小窥. 不像大公司,大公司人多,进来一个新人,甚至十个新人,大家可能都没什么感觉.辞退一个人,或者辞退几个人也再正常不过. 小企业不一样,总共就那么几个人,或者几十个人,谁进来了,谁离开了

移动互联网初创型团队需要什么样的云计算服务?

对于创业型团队来说,服务器托管费用+带宽成费用+运维成本,是压在头上的三座大山.满足业务性能需要,又要降低成本,尽快实现收支平衡,是当务之急. 一.不靠谱的 App Engine 1.Google App Engine 云服务在国外的成功,不代表国内巨头们各种 *AE 仿造品的成功.在微博上搜搜就可以看到小伙伴们吐槽的各种不稳定,另外,*AE们对资源使用最大数各种规定限制,加上为了计费.阉割功能的各种限制,使它的价格优势成为鸡肋.*AE们就好比100M共享带宽的小区宽带,以低价卖给每个上网用户5

[转载]以人民的名义,建立团队工作协议

很多初创团队.以及刚开始尝试敏捷的团队,没有工作协议的概念,热热闹闹,混混乱乱.本文介绍了关于工作协议的What, Why, Who, When, 以及How. What:什么是工作协议 工作协议:由团队共同商议,达成一致遵守的一组规则.纪律.流程的组合,目的是让团队持续保持高效和成功. Why:为什么要制定工作协议 案例1 Jessica是刚组建的Scrum团队的Scrum master.在第一个Sprint中,Jessica发现经常出现一个现象:每日站会总是有人迟到.一开始团队容忍这个情况,