选择分布式数据库

以实际使用场景来看,假设有一个广告系统记录了所有用户在任何时刻触发不同广告的消耗明细,每天大约能产生 5000W 条用户消耗数据明细。现在需要实现一个供流量主可以实时查询这些数据的功能,此时应该选用哪种类型的数据库,在这个应用场景下数据库需要满足以下特点:

  1. 数据量巨大,且面向 C 端用户查询。
  2. 频繁写入且频繁查询,要支持范围查询,且查询性能需要在秒级以内。
  3. 数据存在倾斜的可能性。

传统数据库的瓶颈

MySQL 数据库天生是单机数据库,即它只能运行在一台物理机器实例上,我们没有办法把他拆分开让同一个数据库同时运行在多台机器上。因此它的性能和物理机器实例的配置呈正相关,受到机器配置的制约,机器的天花板上限较低。但是它的好处就是架构较为简单,使用起来更加方便。

Read more »

为什么要使用缓存

在互联网的高流量、高并发场景下,MySQL 集群能够扛住的 QPS 通常在 1W 量级,数据库在达到压力瓶颈时会明显出现慢尾效应,即原有执行速度很快的 sql 耗时也会显著增加,拖累使用了此集群的所有服务,最终导致整个数据库集群的崩溃。

相比于 redis 缓存来说,MySQL 集群的资源更加珍贵,为了保护数据库集群且让服务能够承受更高的流量,我们通常使用缓存来减少数据库的压力,对那些热点数据进行缓存来分担 MySQL 的压力。对于 redis 集群来说,可以轻松承担 10 W+的 QPS,并且可以很方便的进行扩容。

缓存可能出现的问题

只读缓存

Read more »

服务端开发离不开和 http 打交道,无论是 API 请求、RPC 请求,都有可能使用 http 协议。http 太常见了, spring 提供的注解开发可能让我们忽略了协议内不同内容是如何存放,header、body、表单都如何使用。参考极客时间-透视 http 协议,从头到尾梳理一遍 http 的详细知识。

http 是什么

http 全称超文本传输协议,拆分为三个名词详细理解:

  • 超文本:普通的文本指的是文字数据,超文本不但包含了文字,它也包括了语音、图片、视频等数据,是一切资源的泛称。同时它含有超链接,可以从一个超文本跳转到另外一个超文本,形成复杂的网状结构。
  • 传输:数据在双方的流动叫为传输,http 是一个双向传输协议,一般情况下把发起数据传输的称为请求方,接受数据的称为响应方。
  • 协议:首先协议可以分为两个部分,它需要最少两个参与者,参与者要想互相理解对方传输的内容,这离不开规范。简单来说协议就是规定了双方使用同样可以理解的语音进行交流

作为一种协议规范,它本身不是一种程序或软件,HTTP 通常跑在 TCP/IP 协议栈之上,依靠 IP 协议实现寻址和路由、TCP 协议实现可靠数据传输、DNS 协议实现域名查找、SSL/TLS 协议实现安全通信。

Read more »

简单来说,OAuth2.0是一种授权协议,它通过颁发访问令牌的机制而不是使用用户名和密码来请求交互,保证第三方应用只有在成功获取授权之后才可以访问授权者的数据。通过这套协议,用户仅仅通过授权操作就可以免去重复注册的流程,是目前web上重要的安全手段。

OAuth2.0提供了四种许可类型:

  • 授权码许可(Authorization Code)
  • 隐式许可(Implicit)
  • 客户端凭据许可(Client Credentials)
  • 资源拥有者凭据许可(Resource Owner Password Credentials)

OAuth2.0的基本流程

OAuth2.0里有4种角色,分别是资源所有者、三方软件、授权服务和受保护资源,授权码许可的流程如下。

Read more »

kafka介绍

Apache Kafka 是消息引擎系统,也是一个分布式事件流处理平台,企业利用它可以在A、B两个系统之间传递消息,实现松耦合的异步数据传输。总的来说,消息引擎具有两个重要能力:

  • 消息引擎传输的对象是消息
  • 定义了传输消息的规范

消息引擎不在乎A、B两个系统是否相同,它可以在不同系统间传递消息,因此消息的通用格式以及如何传输消息至关重要。kafka的消息格式化使用的是二进制字节序列,消息还是结构化的,只是在使用之前都要将其转换成二进制的字节序列。kafka支持两种常用的消息引擎模型:

  • 点对点模型:也叫消息队列模型,消息只能由A系统发出,由B系统接收,其他模型无权生产与消费消息,简单来说是一对一的模型。
  • 发布 / 订阅模型:有一个topic的概念,可以有多个生产者向topic中生产消息,同时允许多个消费者订阅topic进行消费,简单来说就是一种多对多的模型。
Read more »

NIO

三大组件

1. Channel & Buffer

channel是读写数据的双向通道,连接要读取的文件和内存,可以从channel把数据读入buffer,也可以将buffer的数据写入channel,而stream是单向的,channel比stream更加底层。

简而言之,通道负责传输,缓冲区负责存储

Read more »

基础

Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应。

特点

  1. 一个领导者,多个跟随着组成的集群
  2. 集群中 只要有半数以上节点存活,集群就可以正常提供服务.
  3. 全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的
  4. 更新请求顺序执行,来自同一个Client的更新请求按照发送顺序依次执行
  5. 数据更新原子性,一次数据更新要么成功,要么失败
  6. 实时性,在一定时间范围内,Client能读到最新数据

提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。

Read more »

单例模式

一个类只允许创建一个对 象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。

如何实现一个单例

  1. 构造函数需要是 private 访问权限的,这样才能避免外部通过 new 创建实例;
  2. 考虑对象创建时的线程安全问题;
  3. 考虑是否支持延迟加载;
  4. 考虑 getInstance() 性能是否高(是否加锁)
  • 饿汉式
    在类加载的时候,instance 静态实例就已经创建并初始化好了,所以,instance 实例的创建过程是线程安全的。不过,这样的实现方式不支持延迟加载(在真正用到 IdGenerator 的时候,再创建实例)。
  • 懒汉式
    懒汉式相对于饿汉式的优势是支持延迟加载。这种实现方式会导致频繁加锁、释放锁,以及并发度低等问题,频繁的调用会产生性能瓶颈。
  • 双重检测
    双重检测实现方式既支持延迟加载、又支持高并发的单例实现方式。只要 instance 被创建 之后,再调用 getInstance() 函数都不会进入到加锁逻辑中。所以,这种实现方式解决了懒汉式并发度低的问题。
  • 静态内部类
    利用 Java 的静态内部类来实现单例。这种实现方式,既支持延迟加载,也支持高并发,实 现起来也比双重检测简单。
  • 枚举
    最简单的实现方式,基于枚举类型的单例实现。这种实现方式通过 Java 枚举类型本身的特 性,保证了实例创建的线程安全性和实例的唯一性。
Read more »

IOC

IoC(Inverse of Control:控制反转) 是一种设计思想,而不是一个具体的技术实现。IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。IoC 容器实际上就是个 Map(key,value),Map 中存放的是各种对象。

  • 控制 :指的是对象创建(实例化、管理)的权力
  • 反转 :控制权交给外部环境(Spring 框架、IoC 容器)

IOC 解决了以下问题:

  1. 创建了许多重复对象,造成大量资源浪费;
  2. 更换实现类需要改动多个地方;
  3. 创建和配置组件工作繁杂,给组件调用方带来极大不便。
Read more »

RocketMQ概述

MQ,Message Queue,是一种提供消息队列服务的中间件,也称为消息中间件。消息即数据,一般消息的体量不会很大。简单来说,消息队列就是一种实现“先进先出”的一种数据结构。

用途

  1. 应用解藕:上游系统对下游系统的调用若为同步调用,则会大大降低系统的吞吐量与并发度,且系统耦合度太高。 而异步调用则会解决这些问题。所以两层之间若要实现由同步到异步的转化,一般性做法就是,在这两 层间添加一个MQ层。
  2. 流量消峰:MQ可以将系统的 超量 请求暂存其中,以便系统后期可以慢慢进行处理,从而避免了请求的丢失或系统被压垮。
  3. 消息分发:数据的生产方只需要把各自的数据写入一个消息队列即可,数据使用方根据各自需求订阅感兴趣的数据,不同团队所订阅的数据互不干扰,也不必和数据产生方关联。

RocketMQ的架构

Read more »
0%