分布式缓存

大型分布式电商系统架构演进史

爷,独闯天下 提交于 2019-11-29 02:19:54
概述 本文是学习大型分布式网站架构的技术总结。对架构一个高性能、高可用、可伸缩及可扩展的分布式网站进行了概要性描述,并给出一个架构参考。文中一部分为读书笔记,一部分是个人经验总结,对大型分布式网站架构有较好的参考价值。 作者简介 烂皮猪,十余年工作经验,曾在Google等外企工作过几年,精通Java、分布式架构,微服务架构以及数据库,最近正在研究大数据以及区块链,希望能够突破到更高的境界 一、大型分布式网站架构技术 1、大型网站的特点 用户多,分布广泛 大流量,高并发 海量数据,服务高可用 安全环境恶劣,易受网络攻击 功能多,变更快,频繁发布 从小到大,渐进发展 以用户为中心 免费服务,付费体验 2、大型网站架构目标 高性能:提供快速的访问体验。 高可用:网站服务一直可以正常访问。 可伸缩:通过硬件增加/减少,提高/降低处理能力。 安全性:提供网站安全访问和数据加密、安全存储等策略。 扩展性:方便地通过新增/移除方式,增加/减少新的功能/模块。 敏捷性:随需应变,快速响应; 3、大型网站架构模式 分层:一般可分为应用层、服务层、数据层、管理层与分析层; 分割:一般按照业务/模块/功能特点进行划分,比如应用层分为首页、用户中心。 分布式:将应用分开部署(比如多台物理机),通过远程调用协同工作。 集群:一个应用/模块/功能部署多份(如:多台物理机),通过负载均衡共同提供对外访问。 缓存

分布式锁-redis实现

风格不统一 提交于 2019-11-28 17:27:40
用一web应用集群,负载均衡部署实现: 在上图可以看到,变量A在JVM1、JVM2、JVM3三个JVM内存中(这个变量A主要体现是在一个类中的一个成员变量,是一个有状态的对象),如果我们不加任何控制的话,变量A同进都会在JVM分配一块内存,三个请求发过来同时对这个变量进行操作,显然结果不是我们想要的。 如果我们业务中存在这样的场景的话,就需要找到一种方法来解决。 为了保证一个方法或属性在高并发的情况下同一时间只能被同一个线程执行,在传统单机部署的情况下,可以使用Java并发处理相关的API(如 ReentrantLock 或 Synchronized )进行互斥控制。但是,随之业务发展的需要,原单机部署的系统演化成分布式集群系统后,由于分布式系统多线程、多进程并且分布在不同的机器上,这将原来的单机部署情况下的并发控制锁策略失效,单纯的Java API并不能提供分布式锁的能力。 为了解决这个问题,就需要一种跨JVM的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题! 分布式锁应该具备哪些条件 在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行; 高可用、高性能的获取锁与释放锁; 具备可重入特性; 具备锁失效机制、防止死锁; 具备非阻塞锁特性,即没有获取到锁直接返回获取锁失败; 分布式锁的实现方式 目前几乎所有大型网站及应用都是分布式部署

史上最全的后端技术大全,你都了解哪些技术呢?

做~自己de王妃 提交于 2019-11-28 15:43:30
| 导语 工欲善其事,必先利其器; 士欲宣其义,必先读其书。 后台开发作为互联网技术领域的掌上明珠,一直都是开发者们的追逐的高峰。 本文将从后台开发所涉及到的技术术语出发,基于系统开发、架构设计、网络通信等几个方面让大家对后台 开 发有一个清晰的了解,讲解全面易懂。 系统开发 1. 高内聚/低耦合 高内聚指一个软件模块是由相关性很强的代码组成,只负责一项任务,也就是常说的单一责任原则。 模块的内聚反映模块内部联系的紧密程度。 模块之间联系越紧密,其耦合性就越强,模块的独立性则越差。模块间耦合高低取决于模块间接口的复杂性、调用的方式及传递的信息。一个完整的系统,模块与模块之间,尽可能的使其独立存在。 通常程序结构中各模块的内聚程度越高,模块间的耦合程度就越低。 2. 过度设计 过度设计就是进行了过多的面向未来的设计或者说把相对简单的事情想复杂了,过度追求模块化、可扩展性、设计模式等,为系统增加了不必要的复杂度。 3. 过早优化 过早指的不是在开发过程的早期,而是在还没弄清楚需求未来的变化的走向的时候。你的优化不仅可能导致你无法很好地实现新的需求,而且你对优化的预期的猜测有可能还是错的,导致实际上你除了把代码变复杂以外什么都没得到。 正确的方法是, 先有质量地实现你的需求,写够testcase,然后做profile去找到性能的瓶颈,这个时候才做优化。 4. 重构

Redis缓存,持久化,高可用

与世无争的帅哥 提交于 2019-11-28 12:43:15
一,Redis作缓存服务器 ​ 本篇博客是接着 上一篇 博客未分享完的技术点。 ​ redis作为缓存服务器是众多企业中的选择之一,虽然该技术很成熟但也是存在一定的问题。就是缓存带来的缓存穿透,缓存击穿,缓存失效问题,继而引用分布式锁。 1.1,缓存穿透 ​ 在如今的项目中大多采用垂直的MVC架构,由service层去调用DAO层,然后DAO层再去查询数据库。而redis作为缓存服务器就是在service层去调用DAO层去查询时先去缓存服务器查询,如果存在则直接返回该数据,否则再去查询数据库。由此可知,这么做大量减少了对磁盘I/O的操作,减轻了数据库的压力。 ​ 现在我们假设一种情况,在数据库中存在有id为1到1000的数据。现在如果有人手动去模拟一个id为1001的请求,那么该数据在缓存服务器中是不存在的,因而便会去查询数据库。那么问题来了,如果是一个大量无效的请求去查询数据库。则势必会对数据库造成难以承受的压力,这种情况就是所谓的缓存穿透。 ​ 那如何解决呢? ​ 1,将查询到的null值直接保存到缓存服务器中,但是这种做法并不推荐,因为如果是大量不同的请求id同样会去查询数据库。 ​ 2,接口的限流,降级与熔断 ​ 在项目中对于重要的接口一定要做限流,对于以上恶意攻击的请求除了要限流,还要做好降级准备,并且进行熔断,这种做法可以有效控制大量无效请求。 ​ 3,布隆过滤器 ​

分布式架构浅谈

╄→尐↘猪︶ㄣ 提交于 2019-11-28 10:56:48
http://homeway.me/ 0x01.大型网站演化 简单说,分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。 集群主要分为:高可用集群(High Availability Cluster),负载均衡集群(Load Balance Cluster,nginx即可实现),科学计算集群(High Performance Computing Cluster)。 分布式是指将不同的业务分布在不同的地方;而集群指的是将几台服务器集中在一起,实现同一业务。分布式中的每一个节点,都可以做集群。 而集群并不一定就是分布式的。 之前在网上看到一篇关于大型网站演化的博客。 http://www.cnblogs.com/leefreeman/p/3993449.html 每个大型网站都会有不同的架构模式,而架构内容也就是在处理均衡负载,缓存,数据库,文件系统等,只是在不同的环境下,不同的条件下,架构的模型不一样,目的旨在提高网站的性能。 最初的架构只有应用程序,数据库,文件服务。 到后来,分布式服务、集群架设。 0x02.关于均衡负载方案 在上一篇, 《Nginx反向代理实现均衡负载》 讨论过过的nginx现实均衡负载方案,这里选择另一种HAProxy+Keepalived双机高可用均衡负载方案。 HAProxy是免费

分布式之数据库和缓存双写一致性方案解析

▼魔方 西西 提交于 2019-11-28 01:01:05
为什么写这篇文章? 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作。 但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存。又或者是先删除缓存,再更新数据库,其实大家存在很大的争议。目前没有一篇全面的博客,对这几种方案进行解析。于是博主战战兢兢,顶着被大家喷的风险,写了这篇文章。 文章结构 本文由以下三个部分组成 1、讲解缓存更新策略 2、对每种策略进行缺点分析 3、针对缺点给出改进方案 正文 先做一个说明,从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案。这种方案下,我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存。因此,接下来讨论的思路不依赖于给缓存设置过期时间这个方案。 在这里,我们讨论 三种 更新策略: 先更新数据库,再更新缓存 先删除缓存,再更新数据库 先更新数据库,再删除缓存 应该没人问我,为什么没有先更新缓存,再更新数据库这种策略。 (1)先更新数据库,再更新缓存 这套方案,大家是普遍反对的。为什么呢?有如下两点原因。 原因一(线程安全角度) 同时有请求A和请求B进行更新操作,那么会出现 (1)线程A更新了数据库

MySQL

烂漫一生 提交于 2019-11-27 21:03:59
1.1 mysql 架构   mysql 分为 server 层和存储引擎 1.1.1 server层 连接器:管理连接权限验证 查询缓存:命中缓存直接换回查询结果 分析器:分析语法 优化器:生成执行计划,选择索引 执行器:操作索引返回结果 1.1.2 存储引擎 存储引擎负责数据的存储和提取;其架构是插件式的。innodb 在 mysql5.5.5 版本开始成为 mysql 默认存储引擎。 各存储引擎比对: InnoDB:支持事务,支持外键,InnoDB 是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据,不支持全文索引。 MyISAM:不支持事物,不支持外键,MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的,查询效率上 MyISAM 要高于 InnnDB ,因此做读写分离的时候一般选择用 InnoDB 做主机,MyISAM 做从机 Memory:有比较大的缺陷使用场景很少;文件数据都存储在内存中,如果 mysqld 进程发生异常,重启或关闭机器这些数据都会消失。 1.1.3 sql 的执行过程   第一步客户端连接上 mysql 数据库的连接器,连接器获取权限,维持管理连接;连接完成后如果你没有后续的指令这个连接就会处于空闲状态

记录下最近看分布式系统设计的一些感想(下)

耗尽温柔 提交于 2019-11-27 16:10:28
上一篇文章讨论了分布式系统中的服务调用和异步消息,今天想在这两个的基础上讨论下分布式系统需要解决的问题,以及常见的解决方案。 其实分布式系统的出现和分布式系统面临的挑战归结到最终都是因为用户数量的急剧增长导致的,随着用户数量和活跃用户数的,应用服务和数据库服务的并发访问压力越来越大,我们不得不进行服务拆分,做数据库的拆分和读写分离。服务拆分之后可以让我们能对每个服务进行针对性的部署,核心服务得到更好的隔离。 对于服务的拆分,我们可以根据领域驱动设计的思想,将整个系统进行域的划分,找出我们的核心子域、支撑子域;服务拆分之后面临的一个问题是服务之间的调用,此时RPC就出现了(当然此前还有webservice等技术),而随着RPC的出现,又带来了新的问题,就是服务的治理,例如新的服务上线之后如何让其他服务发现,服务下线之后如何剔除,服务调用超时之后如何进行处理,还有就是服务的性能监控和可用率监控以及相应的报警措施。 同时,有些场景下可能我们不需要同步的调用一些服务,只需要异步通知就可以了,虽然现在的RPC框架也可以实现异步调用,但是当异步调用失败后还是会影响到通知的准确性,于是就有了消息队列。消息队列可以让我们实现服务之间的异步调用,当需要做某一个通知时,我们只需要往消息队列的服务方发送一条消息,用一个消费者去消费这条消息然后调用其他服务即可。同样每一项技术的引入都会给我们带来新的问题

大型网站架构常用解决方案

廉价感情. 提交于 2019-11-27 03:17:41
每个大型网站都是由小变大的,在变大的过程中,几乎都需要经历单机架构、集群架构到分布式架构的演变。而伴随着业务系统架构一同演变的,还有各种外围系统和存储系统,比如关系型数据库的分库分表改造、从本地缓存到分布式缓存的过渡等。 在业务架构逐渐复杂的同时,保证系统的高性能、高可用、易扩展、可伸缩,使框架能有效地满足业务需要,是一个长远而艰巨的任务。本文介绍了五种相关的技术:分布式服务化架构、大流量的限流和削峰、分布式配置管理服务、热点数据的读写优化和数据库的分库分表。 值得注意的是,技术并不是越复杂越好,技术是为了更好地服务业务,只要能达到业务的需求,就是好的技术。简单说就是,即使你有实现复杂技术的能力,没有用户量和利润为基础,也难以落地实施。所以虽然下文中提到了一些框架,但是并不是每一种框架都需要你去亲自实践。很多时候,只是给你提供一个新的思路,一种新的方法,而至于是不是值得被实践,还需要得到业务和用户的考验。 文章目录 分布式服务化架构 集群和分布式 服务化架构,微服务和RPC 服务化架构的组成 服务的横向拆分 服务治理方案 总结 大流量的限流和削峰 分布式系统为什么要进行流量管制 限流方案 削峰方案 基于时间分片的削峰方案 基于异步调用的削峰方案 分布式配置管理服务 热点数据的读写优化 缓存技术 热卖商品的高并发读 基于Redis集群的多写多读方案

分布式之数据库和缓存双写一致性方案解析

百般思念 提交于 2019-11-26 02:30:48
引言 为什么写这篇文章? 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作。 但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存。又或者是先删除缓存,再更新数据库,其实大家存在很大的争议。目前没有一篇全面的博客,对这几种方案进行解析。于是博主战战兢兢,顶着被大家喷的风险,写了这篇文章。 文章结构 本文由以下三个部分组成 1、讲解缓存更新策略 2、对每种策略进行缺点分析 3、针对缺点给出改进方案 正文 先做一个说明,从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案。这种方案下,我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存。因此,接下来讨论的思路不依赖于给缓存设置过期时间这个方案。 在这里,我们讨论 三种 更新策略: 先更新数据库,再更新缓存 先删除缓存,再更新数据库 先更新数据库,再删除缓存 应该没人问我,为什么没有先更新缓存,再更新数据库这种策略。 (1)先更新数据库,再更新缓存 这套方案,大家是普遍反对的。为什么呢?有如下两点原因。 原因一(线程安全角度 同时有请求A和请求B进行更新操作,那么会出现 (1