我的架构经验系列文章 - 后端架构 - 架构层面

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,通用型 2核4GB
简介: 回到索引 http://www.cnblogs.com/lovecindywang/archive/2012/12/23/2829828.html   架构层面:   日志集中 所谓日志集中就是把程序的所有日志和异常信息的记录都汇总到一起,在只有一台服务器的时候我们记录本地文件问题也不是最大,但是在负载均衡环境下再记录本地日志的话就出现问题了。

回到索引 http://www.cnblogs.com/lovecindywang/archive/2012/12/23/2829828.html

 

架构层面:

 

  • 日志集中

所谓日志集中就是把程序的所有日志和异常信息的记录都汇总到一起,在只有一台服务器的时候我们记录本地文件问题也不是最大,但是在负载均衡环境下再记录本地日志的话就出现问题了。在想查看网站日志的时候到哪台机器去查都不知道,难道有100台机器就100台机器逐一远程连上去看?因此,把这些数据汇总在一起保存对于大型网站系统来说是很必要的,这样我们就可以直接进行查看、搜索,也很明确可以知道是哪台机器的业务出了问题。至于这种日志数据是写到RDBMS还是NOSQL甚至是搜索引擎这就看需要了,总之避免写本地的文本文件,否则真的是灾难。当然写一个日志远远没有想的这么简单:

  1. 为了达到比较好的性能,日志是否先写本地内存队列然后定时刷到数据库中去?
  2. 各种日志混在一起也难以搜索,是否要添加一些搜索字段?比如分模块?
  3. 如果数据库不可用的话是不是先写本地日志以后再汇总过去?
  4. 日志是否易于辨明问题还是看日志怎么记录,如果日志中只写错误那么记录了也白记录,一定要写清楚这是哪个模块哪里出现了问题,有条件的话还可以写上一些参数信息和当前的状态。
  5. 对于未处理的异常信息不太可能手动去记录,一般而言很多框架或服务器都会提供一个接口点可以回调我们自己的代码,在这里我们就可以收集这些未处理异常然后统一记录,最后把用户带到友好的错误页面。不记录任何一个未处理异常都是可怕的事情,想象一下用户已经看到了色彩斑斓的页面,而开发还一无所知,这样的话这个问题始终会存在,即使用户投诉了反馈了我们也很难重现。

 

  • 配置集中

配置集中和日志集中的道理是一样的,就是统一管理。任何一个系统其实或多或少都会有一些不能在程序中写死的参数(比如至少的数据库连接字符串和外部服务地址),一般情况下会写到配置文件中,这样存在几个问题,第一就是在多服务器的负载集群情况下要修改配置需要逐一修改每一台服务器的配置,第二就是在修改配置还可以需要重启服务或网站才会生效,第三无法统一管理也无法知道是否所有网站都统一配置了相同参数。解决的办法还是一样的就是汇总保存在统一的地方比如保存在数据库中,然后每一个网站都从数据库中获取配置的值,在实现的时候简单有简单的做法,复杂有复杂的做法,比如要考虑以下问题:

  1. 参数的值是直接保存强类型的那还是保存字符串在使用的时候转?甚至说值是支持对象和数组的,而不是简单类型。
  2. 参数的值不可能每一次获取都从数据库取,怎么做缓存,缓存多长时间,值修改了怎么同步回来?
  3. 程序是否允许修改值?还是说程序只是读取,不允许修改,修改参数的值只能通过数据库或后台进行。
  4. 是否是需要根据不同的部署环境、用户的语言、服务器的IP来设置不同的值。

不管怎么样,至少一个最简单的配置服务,从数据库中读取参数值,哪怕读取后永远缓存只有重启服务才能生效,也会比直接从本地配置文件中读要好很多。

 

  • 缓存

缓存这个架构手段实在是太常用了,几乎所有的人都知道缓存这个设计和性能优化手段。对于一个网站系统来说又有太多的地方可以做缓存,真正能把缓存用好,在合理的地方用缓存,监控缓存的命中率,想办法提高缓存的命中率其实不是这么容易的,一般来说有这些地方可以做缓存,从上到下:

  1. 浏览器和CDN缓存:通过这两种整页的缓存可以尽量减少请求打到网站服务器的机会,也就提高了网站服务器的负载能力,当然一般来说静态的资源比较容易走这种缓存,动态的资源其实也可以走,只不过要能根据访问的条件做出合适的Key,对于和每一个用户都独立的页面可能要直接进行页面缓存比较难一点。
  2. 反向代理的缓存:反向代理作为服务器的代理可以进行整页或是片段页面的缓存,可以提高直接把请求达到网站服务器的机会提高性能。
  3. 数据的缓存:如果请求真正到了网站服务器,那么我们也不一定要所有的数据都从数据库中取,可以尝试把部分数据保存在分布式缓存中。只要Key合理,并且请求有规律那么可以保证比较高的命中率,从而减轻数据库的压力,也减轻网站服务器的压力。
  4. 大块数据的内存中缓存:对于有一些大块的数据是无法保存在分布式缓存中的,那么可以直接在网站启动的时候把这种不太会改变的大块数据全部加到内存中来,这样这快数据的访问效率和计算效率就很高了。

对于缓存的更多内容可以参考我之前做的一个分享:http://www.cnblogs.com/lovecindywang/archive/2010/07/19/1780589.html

 

  • 分布式缓存

所谓分布式缓存就是缓存的数据是分布在多个节点上的,好处是一来可以尽量利用服务器的资源,比如一台服务器可以有1GB内存空闲,找50台服务器就是50GB了,如果不用这50台服务器其实也就是这么多内存空着(一般来说网站服务器使用的内存是相对固定的,主要业务不怎么变化的话,而且诸如Memcached之类分布式缓存对CPU的使用是很低的,完全可以把Memcached寄居在大内存的Web服务器或是应用服务器上,实现神不知鬼不觉的分布式缓存);第二个好处就是可以减少单点故障带来的影响,一般来说分布式缓存都有类似于一致性哈希的算法,即使有单点故障的话也只是少部分缓存数据会不命中,损失不是太大。在使用分布式缓存的时候要牢记下面几点:

  1. 缓存就是缓存,数据是允许排出和丢失的,当成文件系统用的话就错了。
  2. 分布式缓存的数据是通过网络存取的,数据传输走网络和本机内存中效率不能比,而且数据需要序列化和反序列化要考虑到性能开销。
  3. 缓存的Key生成的策略是很关键的,Key生成的参数过多的话很可能命中率会几乎为0,这种缓存做了也白做,因此需要针对分布式缓存的命中率有监控。

 

  • 队列

队列也是实现高性能架构的一个必不可少的利器,通过把执行时间比较长的任务在队列中进行排队,通过限制队列的最大容纳项目数,实现一个抗高压的能力,并且队列后端的点也能有一个比较平稳的压力。队列说到底也只是一个容器,如果前端的压力永远比后端处理能力大的话,队列总是要爆的,因此队列也不是万能。往往对于网站系统即使后端的业务有队列,前端的页面如果扛不住高压力,甚至是验证码之类的都刷不出来的话也是没用的,架构上就是这样系统中任何一个点都会拖累整站的架构,架构优化针对最薄弱的地方而不是最强的地方。形式上来说队列有两种:

  1. 生产者和消费者:生产者生产出来的数据只能被一个消费者消费,也就是任务只能执行一次的。往往这种形式的数据是需要持久化的。
  2. 发布和订阅:任何一个事件都允许有多个发布者和多个订阅者,订阅者订阅自己感兴趣的东西,只要发布者发布了订阅者感兴趣的内容就会传播到所有的订阅者。一般来说这种形式的数据可以是允许丢失的不需要持久化的。

 

  • 池技术

所谓的数据库连接池,线程池都是池技术的一个应用。池技术说到底就是把创建开销比较大的对象缓存在池中避免重复创建和销毁,对象用的时候从池拿出来用,用好了重置后还到池里面别人还可以接着用。比如说数据库连接池就是避免了频繁创建代价高的TCP连接,线程池就是避免了频繁创建代价高的线程。虽然说原理上是这样,但池其实也有一些算法需要考虑的:

  1. 创建的富裕的对象的回收策略怎么做?
  2. 对象损坏怎么处理?

一般来说可以参考网上的池实现方式来实现一个通用的池,这样各种对象都可以进行管理了。

 

  • 分布式文件系统

分布式文件系统并不是所有网站都必须的,一般小网站会把用户上传的图片直接保存在Web服务器本地,这么做是可以的,但量大了之后会有问题,首先一台服务器保存不下怎么办,怎么知道哪个图片在哪个服务器上?其次读的请求怎么进行分离,怎么把图片同步到其它服务器上去。分布式文件系统就是来解决这个问题的,通过把一组服务器当做一个文件系统使得我们的文件资源可以分散保存在多个服务器上并且确保有一定的数据备份。在网站规模不是很大的时候其实可以保存在单台服务器上,然后使用文件同步工具同步到另一台服务器,之前再架反向代理解决,数据量再大一定要分布式的话就要上分布式文件系统了。从原理上来说分布式文件系统其实不是很复杂的,但选型的时候也要进行稳定性和性能的考量。有的人是把数据库保存在数据库中的,虽然这样可以实现单点虽然这样可以实现备份,但这显然不是很合理的,会极大增加数据库的压力。

 

  • 分布式搜索引擎

如果有站内搜索需求的话就要上搜索引擎了,现在开源的搜索引擎非常多,不过很多都是Lucene的封装,在选型的时候要根据自己的需求进行选型。所谓分布式也就是如果单点的索引和查询不能满足性能容量需求的话就需要分布到多点了。从原理上来说搜索引擎主要还是一个分词和倒排索引,但是搜索引擎在内容的排序等细节上点还是有很多算法的,除非必要不推荐自己去实现搜索引擎,可以直接针对开源组件进行封装和改良。搜索引擎做的好其实远远不止全文搜索这么简单,甚至可以根据用户搜索的内容给予搜索的建议,可以根据用户搜索的内容进行索引的自完善,还可以根据用户的搜索结果进行大量的用户行为分析,为网站的产品进行改良,如果站点具有自己的搜索模块的话其实有很多事情可以做的。

 

  • NOSQL

NOSQL就是非关系型的数据库,NOSQL不是用来取代关系型数据库的,之所以NOSQL这么火是因为其性能。从本质上来说,程序就是一组代码,对于相同的硬件配置来说,程序性能的高低也就取决于实现相同的操作要有多少代码在CPU中执行一遍,要有多少IO操作要在磁盘上过一遍,往往通用性的东西就会有比较多的计算和IO,往往定制化的东西性能就会比较高。我们说RDBMS性能不高,但是我们也应该看到RDBMS要确保数据的完整性,持久性,要实现通用的功能,要把它的性能和IO达到内存中然后定期刷磁盘的组件来比就不合理了,因此我们要根据业务在合理的地方使用合理的NOSQL,对于资金相关的业务需要事务的业务不太适合NOSQL,对于允许延迟允许数据丢失需要大访问量的业务比较适合NOSQL。任何一种NOSQL往往都是某个大型公司针对自己的需要定制出来的产品,只有这样定制化的东西才可能实现高性能,因此市面上才会有这么多NOSQL,那么我们在选择的时候也要看这个NOSQL针对的应用场景是否就是符合我们业务需要的。另外,NOSQL逼近是一个新新事物,其用户群不可能有MYSQL或ORACLE这么多,因此我们也不能期望其稳定性能达到非常高的标准,而且NOSQL由于其定制化的特点,在使用的时候不一定都可以通过标准SQL来使用对于学习成本也是我们需要考虑的因素。不管怎么样在该需要用的时候还是要用,有的应用单靠RDBMS是没有可能实现这么高性能的,不用NOSQL就是死路一条,用了即使它不稳定还有可能活。

 

  • NOSQL之Mongodb

Mongodb是一款性能超高的文档型数据库,之所以它这么火不仅仅是因为性能高,而且它功能也很全,相比其它NOSQL它几乎可以实现90%以上的SQL操作,并且也有丰富的高可用性的配置方式。总结下来Mongodb是一款性能几倍于传统RDBMS的最接近于RDBMS功能的NOSQL。对于对性能要求很高,特别是写数据并发要求很高的应用来说使用Mongodb是比较适合的,比如存业务日志或系统日志。值得一提的是:

  1. Mongodb也不是万能的,对于超大级别的数据量如果不进行数据分区,那么Mongodb也救不了你,并且不要期望Mongodb的自动Sharding功能能有多好,自动的毕竟没有手动这么准确,如果你能想到怎么进行数据分片的话还是推荐手动进行。
  2. Mongodb的性能是很好的,但这也是有限度的。只要拥有比较大的内存,那么热数据可以在内存中保存,读取性能不会太差,但是数据量达到一定的限度之后,如果你的索引数据都在内存中放不下的话,那么其性能会很差的,其实我们也很容易想到为什么,举个例子,我们在查字典的时候需要翻索引的,至于字典真正的内容在哪里其实问题不大的,如果一本百科全书即使由100本书构成,只要索引在手里查到了哪一本再去取问题不大,如果这个索引也是由100本书构成,查索引就不能一次性在手里查完还需要翻不同书的话这个性能就会非常差。

 

  • NOSQL之Redis

Redis于其说是一款NOSQL还不如说是一款缓存组件,在大多数时候把NOSQL当成一个服务端可以做计算的,存储复杂类型的,又具有一些诸如队列、管道等小功能的升级版本的Memcached是不错的。我个人使用Redis的心得是:

  1. Redis不像Memcached,它可以保存多种形式的数据,而不仅仅是一个字符串,这是很有亮点的,意味着我们直接可以在服务端针对大量数据进行一个计算,然后服务端直接返回计算结果,而不是要从缓存中把所有数据都取出来在客户端进行一番计算然后再保存回缓存中的(这里的客户端是指使用NOSQL的客户端,不是浏览器),也就是说要用好Redis是要写一些定制性的代码的,把我们真正的业务逻辑嵌入到Redis中去,如果只是存KeyValue的话性能不一定比Memcached高多少的。
  2. 一般情况下不建议过多依赖Redis的磁盘VM的,有16GB内存保存32GB的数据是可以的,有16GB的内存用Redis保存1TB的数据那就是用错Redis了。NOSQL的产品其实原理上来说都不是特别复杂的,使用NOSQL之前最好熟悉一下它的原理,这样我们更容易用好NOSQL产品。总之我的观点还是这样,由于内存和磁盘性能的巨大差异,如果说能在内存中做大部分事情的话,这个性能就会比较好,如果要来回在内存和磁盘上翻腾的话这个性能也好不到哪里去。

 

  • NOSQL之HBase

HBase、Hadoop适合的是超大数据量的存储和计算,它其实是真正的一个分布式的概念,数据不再能在一个单点上保存了,需要分散到很多机器上,然后计算结果也是分别计算后汇总在一起。对于这套东西我的体会是不要轻易引入:

  1. 除非是亿级以上的数据量并且数据的格式比较简单,否则要考虑是否适合引入,HBase的学习曲线不低的,而且最好是在社区熟悉过一段时间的,否则连用哪套版本的Hadoop什么的都搞不清楚,版本没用对要么有很多难以解决的BUG要么就是连基本的连通性都搞不起来。
  2. 要想有很好的性能,至少有20台以上的服务器再来搞HBase,一两台机器就算了,还没到分布式的这个需求。想想也知道所谓通过并行来提高效率首先是你有这么多资源可以把数据并行分散出去,然后同时进行计算汇总才能节约时间,如果根本数据都没分出去怎么可能节省时间。

 

 

作者: lovecindywang
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关实践学习
云数据库HBase版使用教程
  相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情: https://cn.aliyun.com/product/hbase   ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3天前
|
存储 监控 API
构建高效微服务架构:后端开发的现代实践
【5月更文挑战第9天】 在本文中,我们将深入探讨如何在后端开发中构建一个高效的微服务架构。通过分析不同的设计模式和最佳实践,我们将展示如何提升系统的可扩展性、弹性和维护性。我们还将讨论微服务架构在处理复杂业务逻辑和高并发场景下的优势。最后,我们将分享一些实用的工具和技术,以帮助开发者实现这一目标。
|
5天前
|
API 持续交付 开发者
构建高效微服务架构:后端开发的新视角
【5月更文挑战第8天】 随着现代软件开发的演变,微服务架构已经成为了企业追求敏捷、可扩展和灵活部署的重要解决方案。本文将深入探讨如何构建一个高效的微服务架构,包括关键的设计原则、技术栈选择以及持续集成与部署的最佳实践。我们还将讨论微服务带来的挑战,如数据一致性、服务发现和网络延迟,并提出相应的解决策略。通过本文,后端开发者将获得构建和维护微服务系统所需的深度知识,并了解如何在不断变化的技术环境中保持系统的健壮性和可维护性。
41 8
|
2天前
|
Kubernetes API 开发者
构建高效微服务架构:后端开发的新范式
【5月更文挑战第11天】 在现代软件开发的快速演变中,微服务架构已成为企业追求敏捷性、可扩展性和技术多样性的关键解决方案。本文旨在探讨如何构建高效的微服务架构,并分析其对后端开发的影响。我们将通过一系列最佳实践和策略,展示如何优化服务的独立性、弹性和性能,同时确保系统的整体稳定性和安全性。文章还将介绍容器化、API网关、服务发现和分布式追踪等关键技术的应用,为后端开发者提供一份全面的微服务实施指南。
|
2天前
|
设计模式 监控 API
构建高效的微服务架构:后端开发的新范式
【5月更文挑战第11天】 在当今的软件开发领域,微服务架构已经成为一种流行的设计模式。它通过将应用程序分解为一组小型、松散耦合的服务来提供高度可扩展和灵活的解决方案。本文将探讨如何构建一个高效的微服务架构,包括选择合适的技术栈、设计原则以及应对常见挑战的策略。我们将深入讨论如何确保系统的可维护性、可靠性和性能,同时考虑到安全性和监控的需求。
|
3天前
|
监控 持续交付 开发者
构建高效微服务架构:后端开发的新范式
【5月更文挑战第10天】在现代软件开发领域,微服务架构已经成为一种流行的设计模式,它通过将大型应用程序拆分为一组小型、独立和松散耦合的服务来提供更高的可伸缩性和灵活性。本文深入探讨了微服务架构的设计理念、实施步骤以及面临的挑战,并提出了一套实用的策略和最佳实践,帮助后端开发者构建和维护高效的微服务系统。
|
4天前
|
Kubernetes 持续交付 开发者
构建高效微服务架构:后端开发的新趋势
【5月更文挑战第8天】 随着现代软件开发的不断演进,微服务架构已成为众多企业解决复杂系统问题的首选方案。本文深入探讨了微服务架构的核心概念、设计原则以及实施策略,旨在为后端开发者提供一种清晰、高效的技术路径。通过分析微服务的优势与挑战,结合具体的应用实例,文章将展示如何通过容器化、服务网格和持续集成/持续部署(CI/CD)等先进技术手段,实现后端服务的高可用性、可扩展性和敏捷性。
|
4天前
|
消息中间件 监控 Java
构建高效微服务架构:后端开发的新趋势
【5月更文挑战第8天】随着现代软件开发的复杂性日益增加,传统的单体应用架构逐渐难以满足快速迭代和灵活部署的需求。微服务架构作为一种新的解决方案,以其模块化、独立性强和易于扩展的特点,正在成为后端开发领域的重要趋势。本文将深入探讨如何构建一个高效的微服务架构,并分析其对后端开发实践的影响。
|
5天前
|
敏捷开发 持续交付 API
构建高效微服务架构:后端开发的现代实践
【5月更文挑战第8天】 在数字化转型的浪潮中,微服务架构已成为企业追求敏捷开发、持续交付和系统弹性的关键解决方案。本文将深入探讨微服务的核心概念,包括其设计原则、优缺点以及如何在后端开发中实现高效的微服务架构。我们将通过实际案例分析,展示微服务如何帮助企业快速适应市场变化,同时保持系统的可维护性和扩展性。
|
6天前
|
设计模式 Kubernetes 数据库
构建高效可靠的微服务架构:后端开发的新范式
【5月更文挑战第7天】在现代软件开发的浪潮中,微服务架构已经成为一种流行的设计模式。它通过将应用程序分解为一组小的、独立的服务来提高系统的可维护性和扩展性。本文深入探讨了微服务架构的核心概念、优势以及如何利用最新的后端技术构建一个高效且可靠的微服务体系。我们将讨论关键的设计原则,包括服务的独立性、通信机制、数据一致性和容错性,并展示如何在云环境中部署和管理这些服务。
19 3
|
6天前
|
缓存 监控 数据库
构建高性能微服务架构:后端开发的终极指南
【5月更文挑战第6天】 在现代软件开发的浪潮中,微服务架构以其灵活性、可扩展性和容错性引领着技术潮流。本文深入探索了构建高性能微服务架构的关键要素,从服务划分原则到通信机制,再到持续集成和部署策略。我们将透过实战案例,揭示如何优化数据库设计、缓存策略及服务监控,以确保系统的稳定性和高效运行。文中不仅分享了最佳实践,还讨论了常见的陷阱与解决之道,为后端开发者提供了一条清晰、可行的技术路径。