后端好书阅读与推荐(六)

默认分类,编程 2018-10-23 访问: 107 次

后端好书阅读与推荐系列文章:
后端好书阅读与推荐
后端好书阅读与推荐(续)
后端好书阅读与推荐(续二)
后端好书阅读与推荐(续三)
后端好书阅读与推荐(续四)
后端好书阅读与推荐(续五)
后端好书阅读与推荐(续六)

Elasticsearch权威指南

Elasticsearch: The Definitive Guide (豆瓣): https://book.douban.com/subject/25868239/

Elasticsearch是一个强大的开源搜索引擎(不仅如此,还是一个分布式存储实时分析系统),作为后端开发者,我们常常需要用到它,甚至是借鉴其原理来实现自己特定的功能,因为了解一下是很有必要的。这本书不仅讲了使用方法,还讲了原理,很适合我们学习与查阅。

亮点:

  • Elasticsearch使用Java开发并使用 Lucene 作为其核心来实现所有索引和搜索的功能,它的目的是通过简单的 RESTful API 来隐藏 Lucene 的复杂性。也对用户隐藏了分布式系统的复杂性,而且提供了一系列运行良好的默认值,从而让全文搜索变得简单,达到开箱即用的效果
  • ES与传统RDB的对比:
    • Relational DB -> Databases -> Tables -> Rows -> Columns
    • Elasticsearch -> Indices -> Types -> Documents -> Fields
  • ES的自动实现了分片、负载均衡、发现、冗余、选主、同步、扩展迁移、容错等功能。一个节点(node)就是一个Elasticsearch实例,而一个集群(cluster)由一个或多个节点组成,它们具有相同的cluster.name,集群中一个节点会被选举为主节点(master),它将临时管理集群级别的一些变更,例如新建或删除索引、增加或移除节点等。索引只是一个用来指向一个或多个分片(shards,是一个 Lucene 实例)的逻辑命名空间(logical namespace),分片可以是主分片(primary shard)或者是复制分片(replica shard)。索引中的每个文档属于一个单独的主分片,所以主分片的数量决定了索引最多能存储多少数据,复制分片只是主分片的一个副本,它可以防止硬件故障导致的数据丢失,同时可以提供读请求,启动新节点时集群会重新组织并均匀分配各个分片
  • ES提供了丰富的数据操纵功能,不仅有简单的查询字符串搜索(含通配符),还有DSL,可以构建更复杂、强大的查询
  • 批量请求可以减少网络往返次数开销,以及日志数量,可以提升性能(mysql也有这种做法),这个批量的大小要根据你的硬件来定制
  • 倒排索引是全文搜索的核心技术,也就是按照每个单词(经过分词后)划分归属集,存储包含这个单词的文档,检索是按照单词的,所以可以很快返回相关文档
  • ......

此外需要注意的是Elasticsearch发展太快,书籍只是用来系统性的学习的,如果真的要使用起来,还是要去官网看最新的用法,但是基本原理和思想变化是不多的。

大数据日知录

大数据日知录 (豆瓣): https://book.douban.com/subject/25984046/

这本书可以当做大数据领域的字典,包含很多方面,虽然有些地方有一点划水嫌疑(比如一大串单位换算,歌词),但是毕竟瑕不掩瑜,亮点颇多,看完这本书后基本上对大数据就能有一个整体的认识了。

亮点:

  • 大数据没有标准定义,可以用 4V 来表述:Volume(体量巨大)、Velocity(产生速率高)、Variety(类型多样)、Value(需要从海量数据中发现价值)。可以通过大数据生态的一系列工具(hadoop生态)来解决大数据问题
  • 数据分片主要有两种方式:哈希和范围。哈希有:round-robin(亦即哈希值取余,简单但扩展性不佳);虚拟槽(key映射到槽,槽映射到机器,解耦key与机器);一致性哈希(哈希值范围归属,引入虚拟节点后扩展性与平衡性俱佳)。范围有:按不同的主键划分顺序。哈希的问题是范围查询支持不佳,范围的问题是可能冷热数据不均。除了分片问题,为了实现高可用还要解决复制问题,这就会引入各种级别的一致性(强弱)问题和复制策略(全、增量,同、异步)问题
  • 采用独立的资源管理与调度系统与静态资源划分相比有3大好处:减少闲置,提高利用率;增加数据共享能力;支持多类型/版本计算框架。通常具有三种范型:集中式调度、两级调度、状态共享调度,三者逐步弱化中央调度功能、强化框架自由度,适用于不同的应用场景
  • 数据总线的作用是形成数据变化通知通道,当集中存储的数据源(一般是RDB)数据发生变化时,能够尽快通知相关组件。实现有2种思路,双写(需要引入两阶段提交来保证原子性)或者数据库日志挖掘(如 binlog解析)
  • HayStack作为对象存储,其设计有一次写入、多次读取、从不更改、很少删除的特性,由于图片数量很大,所以把多个图片拼在一起减少元数据数量,同时减少元数据属性,这样就可以把元数据放入内存,读取对象时只需要一次内存与一次磁盘访问即可
  • 一般数据多副本用来提高可用性与读取性能,对热数据来说还比较划算,但是冷数据这样就有点浪费,可以用纠删码:数据分成n分,形成m分冗余的校验信息,这m+n分数据最多丢失m份数据依然可以恢复原数据,节约了存储空间,常见编码有Reed-Solomon、LRC等
  • 批处理系统主要有两种范型:MapReduce(两阶段批处理任务,简洁但是表达能力不够丰富)和DAG图计算,可以表述复杂并发任务之间的依赖关系,所以也比较复杂)。Spark本质也是DAG批处理系统,描述能力更强,而且基于内存速度快,对于同一个任务可以反复多次进行,最适用于迭代式机器学习。Storm流式计算,讲究即时处理
  • 常见的流式计算(甚至所有分布式架构)主要分为主从、P2P模式两种,主节点做管理比较方便简洁,而P2P由于去中心化,所以系统管理复杂,该类架构实例较少

Docker—容器与容器云

Docker——容器与容器云(第2版) (豆瓣): https://book.douban.com/subject/26894736/

通过这本书我们来深入了解一下Docker的用法与原理,更主要的是的Kubernates这个编排容器的强大工具的最佳实践与运行原理。最后可以了解下整个容器技术的生态。

亮点:

  • 云计算是一种资源的服务模式,支持随时随地按需从共享资源池中获得所需资源(网络、服务器、存储、应用与服务)且资源可以快速供应并释放,减少了资源管理工作开销。包括IaaS(基础设施如计算、存储、网络)、PaaS(运行时环境设施如数据库、日志服务等)、SaaS(可直接使用的应用服务)
  • 一个软件项目的成功与否与其能否带动一个生态系统的发展相关,docker显然做到了,带动了整个容器技术的发展,而容器技术直接改善了:持续部署与测试、镜像和容器的跨平台支持、环境标准化与版本控制、资源利用率、众多镜像且易于理解和使用
  • 容器云是以容器为资源分割和调度的基本单位,封装整个软件运行时环境,为开发者提供构建、发布和运行分布式应用的平台。容器云专注资源共享、隔离和编排部署时更接近IaaS,容器云渗透到应用支持与运行时环境时更接近于PaaS
  • namespace是linux中实现进程隔离(资源隔离)的主要技术,具体的隔离由几个系统调用clone、setns、unshare和参数完成:CLONE_NEWUTS(主机与域名)、CLONE_NEWIPC(进程间通信常见的包括信号量、消息队列、共享内存)、%%_NEWPID(pid)、%%_NEWNET(网络设备、栈、端口)、%%_NEWNS(挂载点文件系统)、%%_NEWUSER(用户与组)......常见做法是通过clone函数实现,而setns能直接进入一个已有的命名空间
  • cgroups是linux实现资源限制的主要技术(顾名思义就是把一组任务统一加以控制),实现资源(CPU、Memory、IO等)限制优先级分配及其使用量统计任务启停等功能,其本质是内核附加在程序上的一些列钩子,通过程序运行时对资源调度触发相应的钩子达到资源追踪和限制的目的
  • etcd受ZooKeeper和doozer启发,具有类似特点,但也有自己的特色:基于http,用curl就可以使用;可选ssl认证;单实例每秒千次写;使用raft保证一致性。是一个 k v stroe,广泛用于服务发现、发布订阅、负载均衡、分布式通知与协调、分布式锁与竞选、分布式队列、集群监控等
  • 容器云就是以容器为资源分割和调度的基本单位,封装整个软件运行环境,为开发者和管理员提供用于构建、发布和运行分布式应用的平台。直观的云就是一群容器被分组,组间隔离、组内共享,借助全局组件进行管理。有许多工具如“小神器”Compose(dockerfile定义容器,compose定义配置和集群)、跨平台宿主环境管理工具Machine(跨云平台的容器创建与管理)、集群抽象工具Swarm(在多台宿主机上抽象,使得多容器管理接口统一)等
  • Kubernetes是一个(目前最流行的)管理跨主机容器化应用的系统,实现了包含应用部署、高可用管理、弹性伸缩在内的一系列基础功能并封装为简单的Rest API 对外使用。其关键设计就是pod:一组可以互相交互、位于多个宿主的容器组,每个pod都可以有replica来保证高可用和伸缩性

TCP/IP详解 卷1:协议

TCP/IP详解 卷1:协议 (豆瓣) https://book.douban.com/subject/1088054/

TCP/IP是我们日常接触最多的协议,搞后端的总会遇上粘包分包、reset、too many files等等问题,搞懂了TCP/IP才能解决这些问题,这本书对于我们全面深入的了解这个协议栈有很大的帮助。

亮点:

  • 网桥是在链路层上对网络进行互连,而路由器则是在网络层上对网络进行互连。网桥使得多个LAN组合在一起,这样对上层来说就好像是一个局域网,TCP/IP倾向于使用路由器而不是网桥来连接网络,
  • 环回接口(127.0.0.1或者说localhost)允许在同一台主机上的程序和服务器程序通过 TCP/IP进行通信,我们想象一旦传输层检测到目的端地址是环回地址时,应该可以省略部分传输层和所有网络层的逻辑操作。但是大多数的产品还是照样完成传输层和网络层的所有过程,只是当IP数据报离开网络层时把它返回给自己,看上去用传输层和 IP层的方法来处理环回数据似乎效率不高,但它简化了设计,因为环回接口可以被看作是网络层下面的另一个链路层。但是Unix Domain Socket 则省略了一些协议封装的过程,提高了性能
  • ICMP虽然基于IP,但是能反映和控制IP的状况,所以通常就归于IP层。我们常使用的Ping就是利用 ICMP echo实现的,不需要经过传输层;Tranceroute是不停的发送ICMP echo 或者UDP包,逐次增大TTL,直到到达目的主机(亦即不报ICMP超时而是ICMP echo 回复或者ICMP端口不可达),从而获得路径
  • TCP传小报文在公网上容易引起拥塞,所以有Nagle(小于mss的包必须等到前面包收到ack再发,或者多个小分组凑成大分组)和Delayed Ack(ack在一定时间内等顺风车如数据包或者其它ack一起发送,累计Ack)分别在发送端和接收端避免,这也是解决糊涂窗口综合征的办法,但是对于实时性要求较高的应用也需要关闭这些算法
  • TCP在局域网发送可以一开始便发送多个报文段,而在公网上(中间可能有多个较慢的路由器或者链路)一般采用慢启动算法慢慢探测链路的极限,这也是用“乐观”“悲观”两种策略来应对不同的场景,就像悲观锁与乐观锁在不同的多线程竞争程度下的使用性能会有不同体现一样

性能之巅

性能之巅 (豆瓣): https://book.douban.com/subject/26586598/

性能问题横跨诸多领域:CPU、内存、磁盘、网络、代码质量等等,从裸机到虚拟机,本书几乎做到了面面俱到。本书建立在对操作系统的深刻理解之上,甚至于统计学和实验之上,从概念、模型、观测到实验手段,从原理上和方法上来回答了一系列问题如:“如何度量网络繁忙程度”、“服务中断是进程问题还是机器问题”、“SSD与机械硬盘的使用比例是多少”等,让我们在面对性能问题时心中有数,有典可查。同时,也对我们日常的研发起到一个监督作用。

亮点:

  • 本书的序也很棒,都有自己的观点:单进程的瓶颈很好定位与分析,但整个业务的瓶颈有可能不在单元内部,而是单元之间的网络服务,所以要动态分析;无论是调试(debug是静态的)还是调优(tune是动态的)都需要我们既有全局观也要能探微索隐,技术成长的路径是,编码->调试->调优;很多问题解决不了是因为我们不知道我们不知道(性能问题太多太杂),比如不知道设备中断很耗CPU、Oracle session很耗内存(即使不活跃)等,所以说知识的广度和深度都要有才能融会贯通;街灯法(哪里出了问题就找哪里,但实际上问题不一定出在这里)这个观点很新颖,我们要尽力避免,采用科学法:描述问题-假设-预测-实验-分析;性能问题很主观和微妙,本书却提供了一个系统性的方法论
  • 性能是一个全栈的问题(不仅是一般概念上的应用与数据库,还包括os与硬件),所以我们必须要清楚数据的整个流向,通过不同的人员、团队合作(java开发、DBA、网络工程师等),在整个流程中寻找瓶颈,怎么下手需要经验,但是我们可以通过动态追踪(基于CPU指令并在之上动态构建监控数据)收集数据来更好地分析和定位
  • 有已知的已知、已知的未知、未知的未知,性能问题和学习系统是一样的,你知道得越多,你不知道的就越多。但是你了解的越多,那些未知的未知就可能变成已知的未知,最终可以变成已知的已知,所以见识一定要广阔,钻研一定要深入,做个T字形人才。
  • 本文提出了很多性能问题定位方法:街灯法(选熟悉的工具进行分体,比如top命令,这种方法与运气有关);随机变动法(随机找参数修改并观察效果);责怪他人法(可能是其他团队的问题);Ad Hoc 清单核对法(对常见问题列出检查清单,一一尝试);科学法(问题,假设,预测,实验,分析);工具导向法(把手里的工具都用用);R方法(Oracle的性能分析方法,意在找到延时根源);USE法(围绕 使用率,饱和度,错误 三个指标进行分析)...... 这些方法平日我们可能都用过,这里作者却总结出来形成了系统方法论
  • 性能观测工具要么基于计数器(由内核维护的统计数据,默认启用可以视作零开销,一般可以从/proc文件系统中读取,如vmstat,mpstat,iostat,netstat,sar,ps,top)要么基于跟踪(跟踪事件来分析,默认不启用所以有开销,如tcpdump,blktrace,Dtrace,strace,gdb)还有些基于剖析(profiling,对目标进行采样或快照来归纳特征比如CPU使用率、缓存命中率,有oprofile,perf,Dtrace),有进程级别的也有系统级别的。
  • 应用程序性能分析之前首先要定好目标比如延时、吞吐量、资源利用率等,一旦选中目标就可以处理限制该目标的主要因素了,如延时可能是磁盘、网络,吞吐量可能是CPU等。提高应用性能常用技术有:合适的IO大小,IO开销包括初始化缓冲区、系统调用、上下文切换、权限检查、地址映射、驱动代码执行等等,一次IO大小合适既能避免太小导致太多寻道也能避免太大浪费传输能力;缓存,cache提升读能力;缓冲区,buffer提升写能力;轮询,比如poll与epoll,基于事件,避免普通轮询的CPU空转消耗与延时;并发与并行,利用多处理器优势;非阻塞IO,避免较慢的IO成为较快的CPU的“拖油瓶”;处理器绑定,提高内存本地性,减少IO
  • CPU使用率是指一段时间内忙于执行工作的比例,高使用率不一定是问题,可能意味着正在繁忙的工作,但是工作不一定是真正在执行指令,也可能是等待IO导致的停滞周期或者等待锁SpinLock,所以高使用率(每指令周期数CPI也高)不一定是效率高,还要看指令本身的特点,比如CPU亲和性、内存本地性等。
  • 文件系统通过缓存、缓冲、异步等手段可以减轻磁盘或远程系统对应用的影响,所以其性能研究很重要。

本书虽然分为cpu、内存、文件、磁盘等不同领域来说性能,但是有好多命令比如top、vmstat是跨领域的,就重复了很多次,把本来就很厚的书搞得更厚了,所以我们看书过程可以一次性把一个命令搞熟悉,就可以跳过很多重复了。

重新定义团队:谷歌如何工作

谷歌可以说是IT业界标杆,引领了许多潮流:大数据生态、分布式系统、人工智能等等,那么我们就来看看这么优秀的谷歌是如何工作的。

重新定义团队:谷歌如何工作 (豆瓣): https://book.douban.com/subject/26608585/

亮点:

  • 人的主观能动性是有很大力量的,所以企业需要坚信员工都是好的,再就是要有足够的勇气,把员工看成是企业的主人翁, 而不是把他们当成机器。机器会完成工作;主人翁会竭尽所能帮助企业和团队获得成功。你给员工以自由,员工将还你以惊喜
  • 书中反复强调,无法从每日工作中得到一定满足感的人,就是去了薪酬中最好的一部分。你或许不是一家公司的创始人,但是也可以成为一个团队、一个家庭或一种文化的创始人,尽力创造出空间使得其他创始人与自己携手同行。
  • 公司文化要快乐,快乐使我们不必谨小慎微,可以发挥开发和探索的能力,但这只是表面,文化的三个根本元素是使命(让工作有意义)、透明(相信员工,分享数据)和权利(给员工话语权,便于做出高水平决策)。文化塑造战略,而非相反。
  • 聘用水平超过90%应聘者的员工,最糟的情况他们也能有平均水平的表现。这些员工几乎不可能成为公司里表现最差的。但是如果招聘平均水平的员工,不仅会耗费大量的培训资源,而且很可能他们的表现会低于平均水平而不是高于平均水平
  • 我们发现在个人竞争中表现好的人并不总能成为优秀的团队伙伴。赢得这些比赛的人或许很聪明,但通常只是在某一领域有所专长。或者是因为他们习惯于解决有明确终点和确定答案的问题, 而不是掌控现实世界中的复杂状况。 我们在谷歌就有这样的要求, 我们寻找的人不仅能够解决今天的问题, 而且能够解决未来可能出现的各种未知问题

逆流而上

逆流而上 阿里巴巴技术成长之路(豆瓣): https://book.douban.com/subject/27204591/

这本书包含了阿里的许多经验,每一篇都会解决一个特定的问题,当成有体系梳理的博文来看还是很不错的。

亮点:

  • 稳定性要做好几点:研发与运维要靠近、故障标准要统一并强化处理流程、建设统一的基础设施并完善团队融合做到“书同文车同轨行同伦”;坚持技术创新比如新技术、全链路压测与异地多活等;设置专门的岗位与部门来保障稳定
  • 用户使用pwrite写数据,加上O_DIRECT标识,只能保证数据直接落盘(忽略Buffer cache),而文件系统元数据仍然存储在inode cache(内存)中,当加上O_SYNC标识,写操作变为同步写(synchronous I/O),此时可以保证元数据同步落盘。所以我们对整个IO链路理解的越清楚,就越容易看到问题背后的真相
  • 防止缓存被击穿不能简单用预估流量除以单台缓存机器,因为很有可能是按key的hash分布的,有些高频key或者大value的key若处在同一机器则会轻易使此机器超过阈值(并发量与流量)。所以要监控所有key,一旦发现QPS限流或流量限流就要快速定位问题key,再结合使用的散列算法将可疑key分散到各个机器上去,分散压力
  • 去网关化的软负载形式,会将负载均衡策略下沉到客户端,避免网关的单点故障。当然避免不了需要统一的网关作为接入层时,就要考虑同城多机房甚至异地这样的高可用策略。必要的时候要采取自我保护的限流机制,避免雪球效应,一台一台机器接连爆表
  • select * 的弊端一般我们认为是若字段较多或较大对性能有影响,其实不止这样,在分库分表的过程中,这个语句会导致兼容问题,还有其他问题如增加解析成本,不能使用覆盖索引等
  • 幂等控制是资金安全中的重中之重,对于事务、分布式锁、重试等要好好运用,建议在系统设计时,将第三方唯一性的幂等控制作为幂等控制的兜底方案。我最近在玩支付宝的积分换天猫券,因为券很少,需要积分兑换并且抢,这是一个明显的事务:扣积分、得到券。为了安全起见,支付宝提示了可能先扣分但是没有抢到券,事后再把积分还给你,这就是一个典型的补偿机制。本来可以使用两阶段提交的,但是这种做法允许短暂的不一致状态,达到最终一致较两阶段提交更易于编码与理解且数据库消耗增加少

访问原文,来自MageekChiu



本文由 mageek 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。
此文章共有条评论, 人参与 |Powerd By Angboo