IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者
首页 / 阿里巴巴中间件
IT 2016-02-06 10:51:58 / 累计浏览 3,220

限流系统如何发现系统的热点

这篇讲的是如何利用限流系统的内部机制,来解决一个棘手的实际问题:如何在海量调用参数中,实时发现系统热点。 作者从热点的两个核心挑战出发:一是如何在海量参数中只保留最可能成为热点的记录,二是如何在分布式集群中高效汇总统计信息。文章的核心方案巧妙地结合了两种技术:用ConcurrentLinkedHashMap(一种LRU缓存结构)控制内存,仅保存近期访问量最高的参数;同时利用限流系统已有的动态滑动窗口算法,计算这些参数在短时间内的平滑QPS。 对于分布式统计,文章利用了限流系统自身暴露的QPS端口作为数据采集点,并通过多线程任务队列进行快速合并,使得在千台机器规模的集群上也能在数秒内获得结果。最终的性能数据表明,该方案在日常机器上可达到29万的吞吐量,内存消耗可控,有效解决了实时热点发现与系统性能之间的平衡问题。

本机暂存
IT 2016-02-06 10:51:29 / 累计浏览 1,800

弹性伸缩部署

业务快速发展时流量暴增导致超时限流,业务收缩期又闲置大量服务器——这篇讲的是如何用弹性伸缩让资源“活”起来。 作者从实际运维痛点切入,介绍了弹性伸缩中间件的设计逻辑。系统通过监控集群水位、CPU队列等指标自动决策扩容缩容,并提供了观察、自动、计划三种伸缩模式。其中自动伸缩给出了具体策略:比如设置集群水位超过40%且CPU负载持续升高2分钟时扩容,低于13%且空闲持续5分钟时缩容,期望水位控制在35%左右。 文章还拆解了弹性伸缩的运维架构,包含监控大盘、成本分析和自动化部署等模块,并通过架构图和流程图展示了计算资源的动态调度模型。对于大促等可预见高峰,则支持基于业务预估的计划伸缩。 整体方案旨在让无状态应用能根据负载自动伸缩机器,既应对流量洪峰又避免资源闲置,把运维同事从反复扩缩容中解放出来。

本机暂存
IT 2015-02-26 14:05:46 / 累计浏览 3,600

Java跨语言调用实现方案

这篇文章探讨了在大型分布式Java系统中,如何在不改变原有POJO发布方式的前提下,实现跨语言RPC调用。作者指出,随着业务扩展,上层可能采用PHP、Ruby等技术,而底层服务又可能需要用C++、Python来追求更高性能,这就对现有的、基于Java的RPC框架(如Spring Remoting)提出了跨语言兼容的挑战。 文章首先梳理了业界三大主流方案:Google Protocol Buffers、Facebook Thrift 和 Apache Hadoop Avro。作者分析了各自的优劣:Protocol Buffers 的序列化格式高效但RPC能力弱,生成代码有侵入性;Thrift 提供了完整的服务栈和强大的接口支持,但与现有Java RPC体系不兼容;Avro 的动态类型机制灵活,但学习成本较高。 最终,作者提出了一种“扬长避短”的混合解决方案:核心采用Protocol Buffers的序列化格式和代码生成能力,服务接口定义借鉴Thrift的模式,并兼容现有的RPC传输层;同时,利用Avro的Schema机制来实现对原有POJO对象的无缝序列化与反序列化。这套方案旨在保留现有Java RPC架构的同时,优雅地打通多语言互操作。文章还留下了具体实现细节,为后续分享埋下了伏笔。

本机暂存
IT 2013-09-07 15:23:36 / 累计浏览 2,040

数据的存储介质-磁盘的硬件特性

这篇技术文章深入剖析了机械硬盘的硬件特性,从基础构造讲到性能原理,非常适合需要理解存储底层机制的开发者。 作者从磁带机讲起,解释了磁盘如何通过电机旋转盘片、磁头移动寻道来实现随机访问,这个演进过程讲得清晰易懂。文章重点剖析了几个关键点:硬盘如何以“块”(通常为512字节)为单位进行读写,以及在异常断电时,系统如何通过在启动时清理未完成的数据块来保证数据的原子性,这是单机存储保证一致性的经典思路。 更硬核的部分在于对性能指标的辨析。文章厘清了 IOPS(每秒读写次数)、吞吐量(MB/s)和延迟之间的关系,并指出它们适用的不同场景:数据库更看重影响 IOPS 的寻道时间,而大文件存储则更追求吞吐量。作者还用“飞机运旅客”的比喻,巧妙地说明了适度增加延迟可以提升整体吞吐量的原理。 最后,文章总结了机械硬盘技术成熟、顺序读写性能好的优势,以及因机械结构导致随机访问性能下降的固有劣势。

本机暂存
IT 2013-09-07 15:22:50 / 累计浏览 3,460

数据的存储介质-磁盘的RAID

RAID作为存储领域的基石技术,其“分而治之”与“冗余复制”的核心思想,至今仍深刻影响着分布式存储系统的设计。这篇文章从数据存储的两个基本要素——通信管道与介质出发,清晰地拆解了RAID技术诞生的根本动因:通过合理组织多块磁盘,来突破单盘在IOPS与数据安全性上的瓶颈。 文章对几种经典RAID模式(RAID 0/1/5/1+0)的阐述并非简单罗列,而是抓住了它们的核心逻辑与权衡。例如,指出了RAID 0的并行读写优势、RAID 1的镜像成本,以及RAID 5通过XOR校验在冗余与空间效率间的折衷。特别值得玩味的是,作者点明了RAID 0+1与RAID 1+0在故障场景下的关键差异,解释了为何后者是更优的选择,并自然引申到GFS、HDFS等现代文件系统其实都采用了“先复制、再切分”的类似策略。 更深入一层,文章探讨了在单机环境下实现RAID时所面临的、类似于CAP问题的原子性写入挑战。它揭示了RAID卡如何利用“内存缓存+电池/SSD备份”这一巧妙而务实的方案来打破数据一致性的逻辑循环,既保证了性能,也解决了可靠性难题。文中对盘柜及新网络协议(如FC、iSCSI)的提及,则拓宽了读者对RAID物理实现形式的认知。 整体而言,这篇文章将RAID技术置于更广阔的存储演进史中,不仅讲清了“是什么”和“为什么”,更通过与分布式系统的类比,帮助读者理解了这一传统技术历久弥新的底层逻辑。

本机暂存
IT 2013-09-07 15:22:07 / 累计浏览 2,920

数据的存储介质-固态存储SSD

这篇讲的是SSD固态硬盘的性能内幕。作者抛开基础科普,直击几个核心痛点:为什么不同品牌的SSD读写速度差距巨大?为什么解决了磁盘寻道问题后,4K随机写仍是性能瓶颈?而所有问题的答案,最终都指向了一个关键角色——FLASH控制器。 文章从NAND闪存的底层特性说起,解释了SLC/MLC的区别、以及闪存“必须整块擦除”的特殊操作。正是这些硬件限制,导致了“写入放大”现象。作者指出,各家控制器处理垃圾回收、磨损均衡和写入策略的算法差异,直接造就了性能上的天壤之别。对于随机写瓶颈,文章分析了块回收跟不上写入请求时,延迟会从250微秒陡增至2250微秒的残酷现实。 最后,文章探讨了控制器放在专用芯片还是共享主机CPU上的不同路线之争,并展望了随着控制器算法优化和闪存成本下降,SSD将在高性能存储领域全面取代机械硬盘的趋势。读完能让人明白,SSD的水,远比“无机械结构所以快”要深得多。

本机暂存
IT 2013-09-02 13:33:02 / 累计浏览 2,780

数据映射–有序数组

这篇讲的是有序数组作为一种基础数据结构,在实现快速映射查找时的基本原理与技术特性。作者从二分查找需要的两个核心前提——数据有序和可快速取中值——切入,通过一个具体例子(如从有序集中查找4对应的数据),演示了如何通过折半排除逐步定位目标,并解释了其对数级时间复杂度 O(log2N) 的惊人效率。 但文章并未止步于算法演示,而是深入分析了这种简单结构在实际作为存储映射方案时的各项表现。它支持高效的范围查找,但在处理动态插入时会遇到巨大瓶颈,因为保持有序性意味着每次插入可能需要移动大量数据,写入代价极高。同时,纯粹的数组结构并不面向磁盘优化,其二分查找过程依赖的随机读取对磁盘性能是严峻挑战。 作者最后总结道,选择数据结构需基于具体场景,没有绝对的好坏,只有是否合适。这种从基础算法延伸到系统设计考量的分析,为理解存储产品的内部取舍提供了一个清晰的起点。

本机暂存
IT 2013-09-02 13:32:31 / 累计浏览 2,200

数据映射–映射概述

作者从“映射”这一计算机基础数据结构出发,梳理了从CPU到文件系统无处不在的映射关系。文章首先明确了映射的数学定义,并列举了它在查找文件、网络数据、数据库记录等场景中的关键作用。 接着,作者用一组简单对应(如2->4, 1->2)作为示例,对比了三种实现映射的方式:使用集合(如数组)存储键值对、定义一个数学函数、以及编写穷举算法。文章指出,后两种方式因需理解数据规律或硬编码而适用性有限,从而将讨论聚焦于更通用的集合类数据结构。 为了优化最基础的数组线性遍历效率低下的问题,文章深入介绍了两种核心的查找算法:要求数据有序的二分查找(时间复杂度O(log₂N)),以及利用哈希函数实现近乎O(1)效率的哈希查找。作者以哈希查找为例,解释了如何通过键值计算快速定位,并详细说明了“哈希碰撞”问题及使用链表解决的常见方法。 最后,文章总结道,不同的应用场景(如是否需要范围查询、自动扩展、磁盘存储或并行处理)将决定对映射集合的具体技术选择,而这些底层选择正是各类数据库性能差异的根源。

本机暂存
IT 2013-09-02 13:31:54 / 累计浏览 4,240

从需求出发来看关系模型与非关系模型–关系模型与非关系模型概述

这篇讲的是关系模型与非关系模型的选择根源。作者从当前对 NoSQL 的盲目追捧现象切入,指出许多项目初创团队都在纠结如何选择 NoSQL,却忽略了模型本身的本质。 文章的核心是帮读者理清 RDBMS、NoSQL、CAP、BASE 这些概念的本源,并用一个“车”的例子清晰地对比了层次模型和关系模型的差异。关键在于,关系模型通过集合运算抽象了数据“关系”,让用户无需像层次模型那样关心从“车”到“轮子集合”再到“具体轮子”的存取路径,只需关注查询逻辑本身,这使得它严谨且被广泛接受。 然而,随着面向对象编程的普及,关系模型带来了“阻抗失配”问题——将对象中的继承、组合映射到关系表变得非常痛苦。为解决此问题,业界尝试了 ORM 工具、在数据库层支持对象,以及利用脚本语言的动态特性来简化映射。这些方案各有代价,ORM 学习成本高且易导致低效查询,而用 Map 则会破坏封装性。 随着互联网发展,对高性能和灵活数据结构的需求,让层次模型的变种——NoSQL 重新受到关注。文章接下来将从具体应用场景出发,剖析关系模型在哪些地方力不从心,以及 NoSQL 为何又能满足新的需求。

本机暂存
IT 2013-09-02 13:30:54 / 累计浏览 1,660

Solr之缓存篇

这篇讲的是Solr搜索引擎中“看不见”却至关重要的性能支柱——缓存系统。作者没有停留在配置层面,而是直接钻进源码,剖析了Solr四种核心缓存(filterCache、documentCache等)的生命周期是如何被 `SolrIndexSearcher` 牢牢掌控的。 文章清晰地展示了,一次索引提交(commit)如何像一个开关,触发 `getSearcher()` 方法关闭旧的 `IndexReader`,并构建新的 `SolrIndexSearcher`。而新的Searcher一旦构建,它所管理的所有缓存实例便会随之重建。这意味着缓存并非永久存在,其生命周期与底层的索引阅读器严格绑定。 更巧妙的部分在于“预热”机制的设计。文章通过代码片段揭示,当新Searcher被构建时,系统会在后台线程中将老缓存中的热点数据预先加载到新缓存中。这个过程有效避免了缓存“冷启动”带来的性能断崖,确保了搜索服务在索引更新后的平滑过渡。这种从实现原理出发的解读,让读者不仅能配置缓存,更能理解其背后的运行逻辑与优化思想。

本机暂存
IT 2013-09-02 13:28:14 / 累计浏览 4,560

数据映射–平衡二叉有序树

这篇讲的是如何用平衡二叉排序树高效实现数据映射。作者从很多人觉得二叉树“有什么用”的困惑出发,指出其核心价值在于构建一种既能快速查询、又能灵活更新的映射结构。 文章的核心在于阐释平衡二叉排序树如何“麻雀变凤凰”。它在普通二叉排序树的基础上增加了“平衡”条件(左右子树高度差不超过1),使其树高维持在O(log2N)。这直接对应了二分查找的时间复杂度——父节点恰好是左右子树的“中值”,使得查询可以快速排除一半数据。与上周讨论的有序数组相比,两者查询效率相当,但关键差异在于更新能力:数组不支持高效插入,而平衡树通过指针调整(如旋转)即可保持有序与平衡,更新代价同为O(log2N),Java中的TreeMap就是基于此的红黑树实现。 最后,作者从工程视角全面评估了这种结构:它支持范围查找(通过中序遍历)和自动扩展,内存占用通常优于自动扩容的数组。但也明确指出了短板:因指针跳跃特性,它不是面向磁盘的结构;且在调整结构时难以保证原子性,因此并行处理能力较弱。整篇文章通过清晰的对比和特性分析,将经典数据结构与实际应用紧密结合。

本机暂存
IT 2013-08-15 13:40:09 / 累计浏览 4,240

基于Solr的空间搜索(3)

这篇讲的是如何在Solr中实现高性能的地理位置搜索。作者从纯使用GeoHash过滤效率不高的问题出发,介绍了一种结合**笛卡尔层(Cartesian Tiers)与GeoHash**的组合方案。 核心思路是分两步走:在构建索引时,同时为每条记录计算其所属的不同精度层级的网格ID(tierBoxId)。查询时,先用笛卡尔层根据查询范围快速定位一个大致的网格集合,将这些网格下的文档ID存入一个BitSet,完成初步粗筛。随后,再将这个BitSet作为输入,传递给GeoHash距离过滤器。该过滤器遍历粗筛后的文档,通过GeoHash解码出精确经纬度,计算其与查询点的实际球面距离,并过滤掉超出范围的结果。 实现上的一个巧妙之处在于利用了Lucene的FieldCache来缓存GeoHash值,并通过过滤链(Filter Chain)将两层过滤逻辑无缝衔接。作者还展示了一个本地查询实例,验证了这套方案在查询指定经纬度500公里内数据时的有效性。整体来看,这种“粗筛+精算”的两级过滤模式,显著减少了需要进行精确距离计算的文档数量,从而提升了查询性能。

本机暂存
IT 2013-08-15 13:39:11 / 累计浏览 3,240

基于Solr的空间搜索(2)

这篇讲的是Solr+Lucene实现空间搜索中GeoHash方案的源码级剖析。作者从索引构建和查询解析两个阶段切入,展示了如何将经纬度转换为Base32的GeoHash编码存入索引,以及查询时如何通过`SpatialFilterQParser`解析用户的距离查询语法。 核心聚焦在查询阶段的实现链条:从`GeoHashField.createSpatialQuery`生成查询,到`ValueSourceRangeFilter`和`GeohashHaversineFunction`协作过滤文档。作者特别指出了流程中一个可能影响性能的环节——过滤逻辑会遍历索引中的所有文档(从docId=0开始),逐一计算每个文档坐标与查询点的球面距离,并判断是否在指定范围内。源码中也有“TODO: optimize this”的标注,表明作者对这种全量遍历加计算的效率有所疑虑。 整体来看,文章像一次带读者拆解黑盒的代码导读,不仅说明了“怎么做”,也提出了对当前实现效率的思考,为理解Solr空间查询的内部机制提供了扎实的细节。

本机暂存
IT 2013-08-15 13:38:28 / 累计浏览 3,020

基于Solr的空间搜索(1)

这篇讲的是如何在Solr中实现高效的“附近搜索”等空间查询功能。作者从基础原理出发,重点剖析了两种核心方法:Cartesian Tiers(笛卡尔层)和GeoHash算法。 笛卡尔层的思路很直观:把地图像切蛋糕一样分成层层网格。查询周边时,系统只需在几个特定层级的相关网格内搜索,从而大幅减少需要扫描的数据量,这就像一个聪明的漏斗,帮你快速缩小范围。而GeoHash则提供了一种巧妙的编码方式,它将二维的经纬度转换成一维的字符串,比如“wx4g0ec1”。这个字符串本身就像一个地址,前缀代表更大的区域,利用前缀匹配就能轻松实现范围查询,把复杂的空间问题变成了简单的字符串匹配。 文章通过详细的图解和计算示例(比如如何为北京某点的坐标生成GeoHash码),把这两个算法的实现流程讲得非常透彻。理解了这两个基础,你就能明白许多地图应用背后高效的空间检索是如何运作的。文章最后也提到,关于如何在Solr中具体构建索引和执行查询,会在后续内容中展开。

本机暂存
IT 2013-07-10 13:47:02 / 累计浏览 3,780

数据的存储介质-磁盘的RAID

这篇讲的是如何通过RAID技术将多块磁盘组织起来,从而突破单盘性能与安全性的限制。作者从计算机存储的两个基本要素——通信管道与存储介质出发,引出RAID的核心思想:通过数据分区(Partition)提升吞吐量与IOPS,通过数据复制(Replication)保障安全。 文章清晰地对比了几种经典RAID模式。RAID0纯粹追求并行读写的速度,但毫无冗余;RAID1采用全盘镜像,安全但空间代价高昂。RAID5用XOR校验位巧妙地在安全与空间利用率间取得平衡。而现实中更常用的RAID10(1+0)与理论上更优的RAID01,文章通过图示和坏盘场景分析,点明了为何“先冗余后分区”的RAID10才是工程首选。 更深入一层,文章探讨了实现RAID的两种形态:依赖RAID卡、电池与SSD保障日志的单机方案,以及通过光纤通道、InfiniBand等协议连接的外部盘柜。最后,作者将视角延伸至分布式存储,指出HDFS、GFS等系统本质上借鉴了RAID10的思路,并点明了在上层已做复制切分时,底层再用传统RAID可能带来的冗余与性能损耗。

本机暂存
IT 2013-07-10 13:45:23 / 累计浏览 2,560

数据的存储介质-磁盘的硬件特性

这篇讲的是磁盘硬件的核心工作原理,作者从硬件决定软件性能的根本逻辑出发,带我们看懂这个既熟悉又陌生的“老古董”。他从磁盘的老祖宗——磁带机讲起,清晰解释了硬盘为实现“随机访问”而做出的关键设计:让磁介质盘片匀速旋转,由轻量化的磁头臂负责寻道移动,而不是反过来。 文章还深入了一个常被忽视但至关重要的细节:磁盘块的原子写入。它解释了磁盘如何保证在异常断电情况下数据不“写一半”,即通过开机时的检查与清理来维持逻辑一致性。这种“最大努力保证原子性”的思路,是理解单机存储一致性的基础。 对于容易混淆的IOPS(每秒读写操作数)和吞吐量(MB/秒),作者用“飞机运旅客”的生动比喻做了拆解。IOPS看重减少寻道和旋转延迟,适合数据库等小数据随机访问场景;吞吐量则擅长顺序大文件写入,比如视频存储。两者与延迟存在动态权衡关系。 整篇文章用通俗的语言和比喻,把磁盘的机械特性、数据组织方式以及性能指标的内在关联讲得明明白白。对于想优化存储性能或理解上层软件(如数据库、文件系统)行为的工程师来说,这是打下坚实基础的必要一课。

本机暂存
IT 2013-07-07 21:43:12 / 累计浏览 7,200

中间件和稳定性平台

这篇文章全景式地展示了阿里技术体系中,保障大规模分布式系统稳定运行的核心中间件与平台。它不是一个孤立方案的介绍,而是一张完整的技术地图。 文章从配置、消息、服务、数据到性能监控,分层介绍了多个关键组件。例如,用Diamond实现配置的动态推送与超高可用,用Notify(推模型)和Meta(拉模型)满足不同的消息需求,用HSF统一RPC调用,并依靠eagleeye进行链路跟踪。数据层则通过TDDL实现SQL路由,用精卫、愚公等工具解决数据迁移与扩容难题。最后,持续稳定性平台CSP与TProfiler、Hotspot等工具共同构成了保障系统高可用的“运维三件套”。 整篇文章的价值在于,它清晰地勾勒出了一套应对高并发、大数据挑战的、经过生产验证的全家桶方案。对于希望理解超大规模互联网系统底层基础设施的读者来说,这提供了一个非常直接且具体的参照系。

本机暂存
IT 2013-06-17 23:49:02 / 累计浏览 2,620

说说会话串号

这篇讲的是大型网站(以淘宝为例)中一种令人头疼的故障——“会话串号”,即用户意外登录到他人账号的现象。作者基于亲身的运维经历,剖析了几起真实案例。 文章首先区分了两种串号场景:一种是系统BUG导致的,用户不仅能看到别人页面,还能进行操作;另一种是缓存导致的,用户只能看到别人的页面但无法操作。重点在于前两种技术性串号:第一起源于Jboss的Tomcat在解析Request参数时存在BUG,可能读取到脏数据导致登录串号;第二起则是店铺系统在静态化改造时,缓存服务器错误地缓存了包含Set-Cookie的HTTP头,导致用户获得了一个他人的SessionID。 排查这类问题周期很长,因为难以重现且不易定位根因。为此,文章提出了一种主动防御思路:在Cookie中增加一个签名值,并在服务端会话框架中校验该签名。一旦检测到客户端与服务端的签名不一致,就清空会话并强制用户重新登录。这套机制旨在快速发现并阻断串号,将被动排查转为主动防御。

本机暂存
IT 2013-03-03 23:35:46 / 累计浏览 3,400

发布及其检查的自动化实践

这篇讲的是,一个服务实例超过35K的大型Dubbo注册中心,在频繁发布中遇到的棘手挑战及其实战解决方案。作者从一次因人工配置错误导致的严重事故出发,分享了如何通过持续的自动化改进,让发布过程从“危险重重”变得可靠。 文章聚焦四个具体痛点:数据库配置错乱、发布前后服务数据一致性核对、运行时状态报告集成,以及重启引发的动态数据风暴。针对每个问题,都给出了清晰的“解决方法”和提炼出的“原则”。例如,通过监控配置文件的值来防止环境错配;在发布脚本中集成数据Dump和Diff,实现Provider列表的自动核对;将关键状态汇总到一个URL,方便监控;并设计了“warm-up”机制来平滑重启过程。 作者强调,核心思路是将“人操作可能出错”的环节,逐步转化为可监控、可自动执行的脚本。最终目标是让发布回归极简,理想情况下仅需运行一条命令,而把异常情况下的排查留给必要的时候。整个过程体现了从发现问题、分析根因到工具化、自动化解决的工程化实践闭环。

本机暂存
IT 2012-12-21 13:41:32 / 累计浏览 1,980

TermRangeQuery源码解析

这篇讲的是Lucene中`TermRangeQuery`的源码实现。作者从它如何处理一个范围查询出发,揭示了其核心机制:在重写Query树时,会根据查询范围匹配到的Term数量动态决定后续策略。 如果范围内的Term和关联文档较多,为避免性能问题,它会被包装成`ConstantScoreQuery`,通过`Filter`的方式直接获取并遍历文档ID集合。反之,如果Term数量不多,它会被拆解成多个独立的`TermQuery`,用`BooleanQuery`合并结果。这个自动选择的过程,体现了性能与精度之间的权衡设计。 文章进一步通过源码,清晰地展示了从Query树到Weight树,再到Scorer树的生成链路,最终如何遍历并收集文档ID。整个实现的关键在于,通过`MultiTermQueryWrapperFilter`统一了两种路径,将范围查询的最终执行收敛为高效的文档ID集合迭代,巧妙地规避了生成大量Clause可能带来的问题。

本机暂存