当前位置: 首页 > 后端技术 > Java

数据密集型应用系统程序设计-读书笔记

时间:2023-04-02 00:04:25 Java

目前所有的应用系统都是数据密集型的,不是计算密集型的。系统瓶颈不是因为CPU算力不够,而是因为数据量大带来的数据存储。数据计算、数据同步、数据更新引起的一系列问题,可以表现为以下几种形式,如redis与数据库的双写一致性、消息积压、redis集群或MySQL集群中主从节点数据同步等问题,以及redis的持久化问题。包括程序员最大的并发同步问题其实就是短时间内大量数据的计算、存储和更新。目前所有的系统架构设计都有以下功能模块和数据持久化模块,保存我们记录系统状态的数据。常用的是数据库,如MySQL、MongoDB等数据库缓存模块,记录昂贵的系统消耗结果。用于降低系统压力,加快下一次读取速度。比如redis、RocksDB等内存数据库。在搜索模块中,用户可以根据需要通过关键词进行搜索和过滤数据。常见的是ES流处理,将消息发送给其他人进行异步处理,降低系统压力,提高系统响应时间。比如常见的消息中间件MQ批处理用于定时数据同步,比如我们常用的脚本、定时任务等。redis、rocketMQ等各种中间件都有自己独特的使用场景特点,只能高效实现某些功能(比如redis主要用来换缓存,MQ基本用来异步、解耦、削峰),当时MQ开始支持事务性消息,保证分布式事务的支持和补偿)我们的应用代码就是把各种中间件拼接成一个整体,同时保证数据在这些中间件中流动的正确性。如何在系统出现问题时保证数据的正确性和完整性如何在系统面临巨大压力和降级时保证用户仍然有良好的体验如何在系统扩容时保证数据的正确性和完整性是一个问题Reliability,scalability,maintainabilityReliabilityReliability程序在正常使用情况下提供给用户的功能满足预期负载和数据量下的性能要求。该系统可以有效地阻止未经授权的访问。结论是系统在故障的情况下仍然可以继续。为用户提供服务。但失败并不意味着失败。对于应用层的代码,我们在日常业务实现和代码编写过程中的注意事项是避免死锁消耗CPU、内存等公共资源,降低系统整体性能。级联故障,当应用服务所依赖的基础服务异常时,服务不可用或直接将基础服务的错误显示给用户。可扩展性我们的系统旨在随着时间的推移增加用户和数据的数量。如何保证系统在负载增加的同时保持可用就是可扩展性。负载考虑我们每个系统的设计和实现都是针对特定的使用场景和用户,所以在描述系统负载时,不同的系统使用不同的视角。比如有的统计每秒向服务器发送的请求数、数据库每秒处理的事务量、缓存命中率、系统活跃在线用户数等。有时候我们在处理一个请求的时候,会请求很多其他的服务,就会出现一个巨大的扇出。瞬时的系统负载会很高,有时这种请求会消耗大量的系统性能。这种扇出有时可以用作特定场景中的系统负载参数。(fan-out是指当我们为了完成一个请求,发送大量的请求去调用其他服务,虽然我们好像只处理一个请求,但是听说远程调用也会产生很多的请求,比如我们的淘宝或者支付宝或者每年汇总显示你过去一年的消费记录。这个请求其实是一个巨大的扇出)性能描述对于在线系统,我们主要考虑的是响应时间,但是同一个请求响应每个请求服务的时间可能不同,有时会受到网络丢包、垃圾收集停顿、线程上下文切换、内存页面切换等的影响,有时响应时间最长的用户可能是最后一个有价值的客户。一般情况下,响应时间越长,处理的数据越多,客户价值就越大。有时还会出现堵头现象。由于服务器CPU数量有限,只能并行处理一定数量的事务。只要阻塞了少量的请求块,就会阻碍后续的请求处理,所有后续客户端的响应时间都会变长。有时当一个请求需要多个后端请求时,这个请求的响应时间就变成了最慢的请求响应时间。