程序员的自我修养
Home » 标签 » tsukkomi

架构师做什么?

0条评论770次浏览

记得我最早思考这个问题的时候还在国企,那会刚参加工作没多久。某天突然看到有人的职位是架构师,于是很好奇,作为一个架构师,他/她的日常工作是做什么?或者这么说,你要能够做些什么,才能成为一个架构师?

然而,作为一个低端码农,对这个问题一直无解。而且还受到国企那些架构师的影响,一度以为架构师就是一群没能力做开发,只会满嘴空炮,开一个又一个浪费生命的会议,写一堆自己都不愿看第二遍的文档的复制粘贴机器。

前几天梳理后端架构,过程中有很多想法,例如这里当初这么设计不是没事找事?这样设计这个模块岂不是没法扩展?当初要是不这样设计现在工作量岂止减少10倍?!突然间我意识到,架构师的工作,是不是就是处理这样的事情——让系统/服务/产品等后期更容易维护/扩展,不至于被后来者诅咒?

程序员为自己写的代码负责,为自己弄出来的bug买单。除此之外,一个系统/服务/产品是否就没有其他方面的问题了?比如程序员按照设计用redis来缓存数据,现在内存不够用了,是程序员的锅吗?当初采用了http+json作为内部通信协议,现在随着业务增长和新的需求,发现http+json的效率更不上了,是谁的锅?某个mysql表的字段设计成了text,导致现在稍微大量点的写入就主从延迟超过阈值,这是谁的锅?

诸如此类,或大或小、或轻或重的问题,我想应该就是架构师来处理的吧。

对于架构师做什么,现在只有这点浅薄的认知,希望以后成为架构师(不是国考的系统架构师)后再写文章补充吧。

如何成为架构师?我觉得除了脑子必须特别好用这种基本要求外,还需要丰富的经验和特别广的知识面,而且需要专精一两个领域。

比如你得知道kafka作为MQ,可靠性有多少,TPS/QPS有多少,作为整个系统的消息中心,是否可以信赖;

你得知道redis的QPS和TPS是多少,是否会因redis存在瓶颈,如何设计key可以方便从单机redis扩展为集群,或者小集群扩展到大集群。

你得知道http/thrift等通信协议的优缺点,不同场合做出不同的选择。

你得知道mysql能撑住的量是多少,字段类型设计成什么样能满足需求又不失性能。

你得知道hbase、mongodb试用什么场合,都有什么坑。

你得知道响应N万QPS http请求需要什么样的框架,需要几台机器。

你得知道处理流数据storm和spark应该选哪个。

如何高可用?需不需要冷备热备?如何监控报警?系统中某个节点挂掉怎么办?服务解耦到哪种粒度?

是否所有需求都应该满足?哪些需求可以判定为不合理需求?
......

(以我目前的见识和经历,也只能想到上面这些。[捂脸])

等一系列的事情,这样才能在设计阶段,就能看到以后可能遇到的坑。

这里再记录下现在工作中遇到的一些坑:

  • mysql的某字段设计成为text,实际上设置成为varchar完全能够满足。text导致主从延迟十分大。如何确定的?弄了另外一张完全一样的表,将text改成varchar,就完全没有主从延迟了。但现有数据量太大,改变字段类型起码会锁表30分钟以上,完全不可接受,最后只能切换到另外一张表才解决问题。
  • 无效devicetoken存放在单机redis中,设计成为以app为key的set,某些巨型app的无效devicetoken可能上千万。后来单机redis的qps满足不了高峰期的查询需求,只能改成集群redis。但现有的key设计导致同一个app的数据只能存在一台redis上,根本解决不了问题,高峰期压力无法分散开来。最后将key设计成appkey+devicetoken的形式才解决问题。
  • redis集群的proxy问题。最开始我以为codis/twenproxy的proxy和hbase的master/zookeeper一样,不负责数据传输,只负责存储些meta信息,真正的数据交互式client和实际worker交互。结果发现只有一个proxy的情况下,qps和单机一模一样。后来进一步了解到原来proxy是要进行数据传输的,想要提高qps就得增加proxy数量。比如4台redis组成的集群,需要4个proxy才能发挥出全部的性能。
  • 同样的mongodb的proxy(mongos)也进行数据传输,后来全部改成多个proxy了,既发挥出了集群的全部性能,又消除了proxy的单点故障。
  • alias和tag的设计问题。这个就涉及到具体的业务了,大致的情况就是对这2个接口没有做任何的限制,基本的长度限制都没有,导致开发者/黑客滥用接口,alias库里面各种超过4MB长度的数据,有的甚至把整个网页当成alias,有的全部是各种攻击注入sql。而更多的开发者弄不明白alias和tag的区别,把两者混用,把tag当成alais,导致后端查询压力巨大,把alias当成tag,导致数据库完全存储不下。这个问题至今没有完美的解决方案,当初设计上的想法是好的,可不是每个用户都是按照设计的想法来的。永远不能小瞧用户的创造力/破坏力。从最开始,就应该有严格的限制来引导开发者正确的使用各个接口。没有限制往往带来的是灾难。
  • 存储在redis中的数据没有设置ttl。当初选择将数据存放在redis时就应该考虑到ttl。现在的结果是接近1T的数据,用了9台价值7-8W的机器,存放在redis集群中。而这个集群的qps是多少?1W都不到!一台redis就可以满足qps,但因为历史数据无法删除,导致只能不断扩展集群大小。根据dau等其他方面推测,这接近1T的存放在redis中的数据,最多只有30G的数据是有效的数据。
  • 没有防爆量设计。每个集成了sdk的app都会在一些事件的触发下发送http请求到服务器上。而有的集成有误的app可能会导致请求量暴涨到服务端无法处理的地步,可能只是log文件就能撑爆硬盘。这个问题到现在也没有解决,现在每次遇到爆量都只能硬编码。其实解决起来很简单,方案我也出了,但因为一年可能都遇不到两三次爆量,所以老大就一直觉得无所谓不用浪费时间开发这个功能。
  • 定时任务太多。很多业务数据都靠定时脚本上传数据到hdfs上再计算,每当遇到新增服务到新机器,服务转移到其他机器等情况,就会出现忘记部署定时任务的情况,从而导致业务数据计算有误差。现在解决方案是所有需要上传的数据写kakfa(实际上本来就会写kafka),然后后端spark streaming消费并写到hdfs上。干掉所有定时任务真是一身轻松。
  • 不合理的需求应该拒绝。某汪*带盐的网站家的app,大概累积设备量不到30W,每次广播打开数在7000左右。就算这7000个打开都在同1秒,那他们的服务器的qps也不过7000,况且这7000个打开是24小时甚至更长时间内陆续打开的。就这样的压力,他们就受不了了,要求我们把发送速度降到100/s。如果真的降到100/s正常情况下也就不到10s能发送完的任务我们需要40min才能发完,这意味着一台服务器在40min里只能龟龟龟龟速的发送这个任务。为了这个需求修改服务?我觉得除非吃多了,不然绝对不可能满足这样的需求。然而,我觉得的没用,你们懂的。[大哭]
分类:杂七杂八, 随想
标签:

Sqoop2初步使用感受

8条评论8,414次浏览

最近将公司各个运营点的集群逐步转移入CDH。第一个遇到的问题就是Sqoop2的使用问题。

具体说来,分为下面几个方面。

Date类型字段的parse错误

测试sqoop2的时候就简单的测了下varchar和number类型的数据,发现没问题后就写了报告。现在我知道错了。

实际使用过程中,发现遇到表中有Date类型的column时,所有的job都会报以下错误:

2015-01-28 16:22:29,964 INFO [IPC Server handler 0 on 55187] org.apache.hadoop.mapred.TaskAttemptListenerImpl: JVM with ID : jvm_1422410148386_0003_m_000002 asked for a task
2015-01-28 16:22:29,966 INFO [IPC Server handler 0 on 55187] org.apache.hadoop.mapred.TaskAttemptListenerImpl: JVM with ID: jvm_1422410148386_0003_m_000002 given task: attempt_1422410148386_0003_m_000000_0
2015-01-28 16:22:35,516 FATAL [IPC Server handler 2 on 55187] org.apache.hadoop.mapred.TaskAttemptListenerImpl: Task: attempt_1422410148386_0003_m_000000_0 - exited : org.joda.time.LocalDateTime.parse(Ljava/lang/String;)Lorg/joda/time/LocalDateTime;
2015-01-28 16:22:35,517 INFO [IPC Server handler 2 on 55187] org.apache.hadoop.mapred.TaskAttemptListenerImpl: Diagnostics report from attempt_1422410148386_0003_m_000000_0: Error: org.joda.time.LocalDateTime.parse(Ljava/lang/String;)Lorg/joda/time/LocalDateTime;
2015-01-28 16:22:35,524 INFO [AsyncDispatcher event handler] org.apache.hadoop.mapreduce.v2.app.job.impl.TaskAttemptImpl: Diagnostics report from attempt_1422410148386_0003_m_000000_0: Error: org.joda.time.LocalDateTime.parse(Ljava/lang/String;)Lorg/joda/time/LocalDateTime;
2015-01-28 16:22:35,542 INFO [AsyncDispatcher event handler] org.apache.hadoop.mapreduce.v2.app.job.impl.TaskAttemptImpl: attempt_1422410148386_0003_m_000000_0 TaskAttempt Transitioned from RUNNING to FAIL_CONTAINER_CLEANUP

(更多…)

分类:Apache Sqoop2
标签:,

战5渣系列——奇怪的Pig特性

8条评论12,317次浏览

最近连续2次发烧+工作比较忙导致好久没更新。今天更一发战5渣。

先感受下战5渣的境界:
only5

背景简介

用存储过程分分钟能搞定的事情,老总非要用hadoop跑,曰:hadoop是我们的核心竞争力。用hadoop的话算上导数据的时间,估计用时怎么也要6个小时左右。但这不是重点。重点是用pig计算出来的结果和存储过程跑出来的不一致,于是苦逼的排错之旅开始了。

第一个bug

第一个bug叫做“人祸”。队友发来的数据库表的文档居然漏掉了一个字段,于是这个字段后面的列全部对应错了。而我用pig又喜欢用X = FOREACH B1 GENERATE $4,$5,$16,$21,$45,$77,$81,$92,$47;这样的风格,并且加上如下注释:

好了不开玩笑了。虽然这个问题很没有技术含量,但教会了我这么一个真理:永远不要相信其它人,若确实需要相信其它人请选择性的相信那些靠谱的人!

第二个bug

第一个bug完全体现不出我是战5渣这么一个事实,那么第二个bug就能很好的诠释什么叫战5渣。

(更多…)

分类:Apache Pig, 战5渣
标签:,

LeetCode编程练习(2)

7条评论9,946次浏览

Max Points on a Line

题目

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

答案

思路:时间复杂度O(n^3)的情况下是肯定可以算出结果的,那么意味着通过空间换时间应该是可以让时间复杂度达到O(n^2),这是我自己发明的定律。首先定义静态内部类Line,用于表示两点计算出来的直线,考虑到Double类型的精度损失问题,Line采用三个属性来保证精度上的完整性。然后重写hashCode()equals(..)方法,使得同一条直线相等,且在Hash值上相等。如此通过2个 \(n(n-1)\over 2\) 次循环即可获取到结果,时间复杂度为O(n^2)。
(更多…)

分类:Java语言
标签:,

LeetCode编程练习(1)

1条评论10,717次浏览

看到Leetcode 编程训练这篇文章,于是也开始尝试扫题。上面的题目基本是毫无实际用处的,但是训练下编程还是可以的。做题过程中感受到了一些平常没有的感觉(不要问我是不是查克拉流动的感觉,我还没具体的感受到),反正感觉应该对自己挺有用的。不过,也出现了很多让人想吐槽的bug(或者是我太弱了,还无法理解原因)。

Min Stack

题目

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

  • push(x) -- Push element x onto stack.
  • pop() -- Removes the element on top of the stack.
  • top() -- Get the top element.
  • getMin() -- Retrieve the minimum element in the stack.

答案V1

采用一个TreeMap来保证随时可以获取到最小值(好处是最大值也能获取到,虽然题目中没有这个要求),提交答案后得到结果:Memory Limit Exceeded
(更多…)

分类:Java语言
标签:,

也谈“最糟糕的编程面试题”

4条评论6,201次浏览

长假过后的第一天,突然看到一篇让我十分有共鸣的文章——最糟糕的编程面试题。这篇博文主要吐槽了面试题中最常犯的2个问题:太过困难不切实际。而文中举的例子:如何检测链表是否存在环路,也恰巧是我曾经被面试过的一道题目。而那次面试也堪称我面试经历中最让人难(dan)忘(teng)的一次。

第一个故事——最难忘的面试

背景:校招,笔试通过后连续三轮面试,每轮都会刷一部分人,具体是那个公司就不说了,相信去过的同学基本都能猜出来。第一面,自我感觉表现一般,等结果时一直在想会不会一轮跪。结果这个岗位19个面试者刷了13个,我有幸留下了。第二轮,自我感觉十分良好。面试官问了很多这样的问题,如:如何判断两个链表是否有共同的尾巴、字符串相似度、链表中两元素交换等等。

后来他问到如何检测链表是否是环形链表,也就是首尾相连的链表,我当时想了想就答道,用2个指针,开始同时指向一个节点,然后一个指针移动,另外一个不动,若它们再次指向同一个节点,则是环形的。面试官笑道,用2个指针的想法不错,能否继续改进?我想了想,时间复杂度已经是O(n)了,难道要变成O(lgn)?那岂不是要借助于树之类的方法?这貌似有点太难了,短时间之内无法搞定。面试官看我犹豫了很久,提示到,还是使用2个指针,你再想想有没有其它的方法。然后我纠结了半天后,尝试的说了个当时觉得很粗(cao)糙(dan)的方法:一个指针走2步,一个指针走1步。没想到这尽然真是面试官的“标准答案”。面试官笑呵呵的说,不错不错。于是我心里一阵阵小激动,看来不用多久,我就会升职加薪,当上总经理,出任CEO,迎娶白富美,走上人生巅峰,想想还有点小激动呢。

阅读全文>>

分类:面试
标签:
11
profile
  • 文章总数:79篇
  • 评论总数:254条
  • 分类总数:31个
  • 标签总数:44个
  • 运行时间:1193天

大家好,欢迎来到selfup.cn。

这不是一个只谈技术的博客,这里记录我成长的点点滴滴,coding、riding and everthing!

最新评论
  • Anonymous: :arrow: :neutral: :cry:
  • Anonymous: java.io.NotSerializableExcepti on: DStream checkpointing has been enabled but the DStreams with their...
  • wick: HI,请问一下,U,S,V得到后,怎么得到近似矩阵呢(用sp ark java),谢谢。
  • Michael Whitaker: Thank you for this blog, it was very helpful in troubleshooting my own issues. It seems that no...
  • Anonymous: :mad:
  • Anonymous: :???:
  • Anonymous: :mad: :mad: :mad:
  • 洋流: 哥们,我问个问题,你把testOnborrow去掉了。。如果 得到的jedis资源是个不可用的,服务从来都不出问题么?
  • 洋流: 哥们,我问个问题,你把testOnborrow去掉了。。如果 得到的jedis资源是个不可用的,服务从来都不出问题么?
  • Anonymous: :razz: :evil: :grin:
  • 张瑞昌: 有很多,比较常见的是Jacob迭代法,一次迭代O(n^3), 迭代次数不清楚。 如果是手动算的话按照定义求就可以了
  • Anonymous: :mrgreen:
  • lc277: 你好 我想问下一般删除节点要多久,要删除的datanode大概用了 1t,解除授权已经30多小时还没完成,请问是出现什么问题了吗 麻烦告诉下谢谢 qq1844554123
  • Anonymous: 你好 我想问下一般删除节点要多久,要删除的datanode大概用了 1t,解除授权已经30多小时还没完成,请问是出现什么问题了吗
  • Anonymous: :smile: :grin: :eek:
  • 李雪璇: 想要完整代码,可以帮忙发给我吗
  • Anonymous: 请问一下,那个 user的推荐结果楼主查看了么? 为什么输入数据 最高是五分,输出结果都是7分8分啥的?怎么设置输出的分数的最 大值?
  • Anonymous: 那个 user的推荐结果楼主查看了么? 为什么输入数据 最高是五分,输出结果都是7分8分啥的?
  • Anonymous: stopGracefullyOnShutdown在yarn- client模式下我测试的无效,你的呢
  • Anonymous: 另外,import的lib包能否发个列表.