【聊聊MySQL】二. InnoDB体系结构
【聊聊MySQL】一. MySQL存储引擎
一.MySQL介绍
作为 MySQL
系列的开篇,我觉得还是有必要说说大家熟悉的 MySQL
数据库的一些东西。 MySQL
我想作为开发者应该没有人不认识或者不熟悉了吧。不管所在的厂子是大中小,基本上很多时候都会采用 MySQL
作为我们数据的存储介质。当然政府项目很多都会采用 Oracle
数据库,不过最近看来,这个事情貌似也不是绝对。也有很多政府的项目已经决定采用 MySQL
或者其他厂商封装的 MySQL
分支了。 作为数据库,其实定义是这样的:
- 数据库:文件或者其他文件类型的集合,在
MySQL
中,文件被存储为frm
myd
ibd
等多种形式的文件。而有些存储引擎比如NDB
他的数据信息则是被存储在内存之中的,并不会持久化到硬盘上面,所以他不需要文件来进行存储。速度稍稍快但数据库出现异常重启的话,数据就会丢失。 - 数据库实例或软件:其实就是运行的,可以读取以上数据库文件的软件进程,他可能是一个也可能是多个,日常开发经常是运行一个的情形。我们运行
SQL
或者其他操作的,其实都是在跟数据库实例进行交互,数据库实例会根据命令,计算出来比较高效的查询策略在硬盘上进行数据查询。
Netty处理WebSocket,Nginx配置
一.实时消息WebSocket
传统的 WEB
开发中,通常我们渲染数据或者请求增删改的时候,都需要通过发送 HTTP
请求。 而每次发送 HTTP
请求基本都需要经历下面的历程(其实和 TCP
大致相同): 而当我们需要一些实时消息的需求的时候,比如聊天或者消息推送,那么我们有一种做法就是。浏览器每隔几秒轮训一次服务器(因为不请求服务器就没法回复消息),走一下上面的步骤,然后服务器如果有数据响应数据,没有数据就响应空的数据。哇啊啊啊啊你看这个过程,如果我的后台系统这个账号刚好没什么生意,基本很少需要推送有人下单的消息给我,可是我还是要走这些流程,服务器也还是需要处理我这个没用的卖家的请求。 当然并不是这种方式没人采用,还是有的,因为开发简单。但是性能其实并不怎么样,而且还要浪费一个服务来处理这个请求。 这个问题看起来还是比较棘手的而且很迫切的一个需求,于是乎我们的 W3C
组织站了出来,为浏览器新增了一个新的协议 WebSocket
协议,在 HTML5
发布的时候新增进去的。 WebSocket
跟 HTTP
在同一层,利用 HTTP
向服务器请求升级 WebSocket
,服务器应答即可将当前的连接升级为 WebSocket
连接。
1 | GET ws://localhost:9999/ HTTP/1.1 |
服务器如果答应了,就会响应:
1 | HTTP/1.1 101 Switching Protocols |
这时候相当于说,我浏览器和服务器经历了三次握手,然后在中间建设了一个管道。 这个管道,谁都可以随时使用,客户端和服务端都可以同时发送消息。也就是说在上面订单通知的例子中,我服务器收到了一个订单支付成功,即可立马发送一条消息给你客户端。
Netty之ByteBuf以及编解码器
一.数据传输的容器ByteBuf
1.1. 简单理解一下
OK,上一篇文章我们大致了解了 Netty
在运行过程中所需要的一些组件。接下来需要慢慢的深入了解这些容器了。 为了方便回忆,我先贴一段上一篇的代码:
1 | ... |
我们可以看到,在服务端代码中,使用了 ByteBuf
来读取客户端所传递的消息,然后实现逻辑,再使用 ByteBuf out = Unpooled.copiedBuffer(newMsg.getBytes(Charset.defaultCharset().name()));
来将处理后的数据重新封装成字节,从而写出去,传递给客户端。 所以大概猜一下,ByteBuf
是一个装载着数据字节的容器,在 Netty
中通过网络进行传输。客户端又重新解码,读取出服务端返回的数据。 其实,jdk
自己的 NIO
也有个类似的类 ByteBuffer
,但是这个类,他不太灵活,所以 Netty
才决定重写这个类,从而达到一些比较灵活的目的:
- 可以被自定义缓冲区类型拓展;
- 通过内置的符合缓冲区类型实现透明的零拷贝;
- 容量可以自增;
- 读写模式不需要来回切换(得益于读写指针);
- 支持链式调用、引用计数以及池化计数。
Netty组件以及入门体验
零.Netty
其实了解到 Netty
已经很久了,一直想用,但是因为之前的水平还不够格,回调事件 TCP
什么的还没感觉,所以学起来一头雾水,加上官网的文档,哎呀,官网貌似就没有文档只有示例代码,读不懂。 写了挺多的回调函数,渐渐地有了感觉(通常使用 CompleteFuture
来请求其他服务的数据信息,请求完在执行自己的业务)。其实我也不知道我做了什么,貌似什么没做就突然融会贯通了,所以我感觉理解回调还是蛮重要的一点吧。 突然看到自己的书本库有本书《Netty实战》翻起来阅读,还是蛮好的,这篇文章其实是我读这本书,加上自己的一些理解写出来的。 Netty
是什么应该没人不会知道吧,就是 Java
行业中一个能够顶级处理网络通讯的轻量级框架,如果公司在使用 Dubbo
或者 Thrift
的话,那么也是间接在使用 Netty
框架了。所以学一学无伤大雅还可以了解一些很有趣的东西。
一.Netty服务端
所有 Netty服务器
通常需要以下两部分:
- 至少一个
ChannelHandler
来接手客户端的数据以及处理数据; - 引导服务器启动的配置,配置启动参数,这个就没啥好说的了。
ChannelHandler
是 Netty
中一个接口族的父接口,它主要负责接收和响应事件通知。 在 Netty
中 ChannelHandler
有很多默认实现,用来处理服务器中常见的数据传输问题。 因为服务器会响应传入的消息,所以需要实现 ChannelInboundHandler
接口,用来定义响应入站事件的方法。由于刚开始的程序只需要简单的方式即可,所以我们实现 ChannelInboundHandlerAdapter
即可,他提供了 ChannelInboundHandler
接口的默认实现。 我现在想要简单的实现一个服务,就是能够把把我发送的字符串,给反转过来,即发送 abc
服务器给我响应 cba
。
SpringCloud服务使用ProtolBuffer编码进行传值
前言
我们知道,使用 SpringCloud
技术栈,上下游传值的方式一般使用 form
表单或者使用 JSON
格式进行传值。但是我感觉,我们内部服务进行传值的时候,还使用这两种类型的方式,显得有点重。所以在查询了 Java
界以及其他语言序列化对象的时候,查询到了几个常用的序列化工具:kryo
Hession
JSON
XML
Protocol Buffers
JSON
XML
就不必多言,使用 Java
语言开发的基本都知道。 kryo
效率高,使用二进制文件进行传递,但是有个缺点就是不能跨语言。 Hession
效率稍稍差一点。 那么剩下的 Protocol Buffers
就是能够弥补上面的缺点,并且带来一个新的缺点:需要编写静态的 .proto
文件使其项目启动的时候,静态编译映射规格。不过速度高,跨语言,这点缺陷我还是可以接受的。 基本确定方向以后,那么本文就从怎么使用 .proto
将其整合到我们常用的 SpringMVC
中去,使其序列化和反序列化的过程对我们业务开发不可见。
ProtocolBuffers入门
ProtocolBuffers
规则是这样的:编辑 .proto
文件,使用编译器编译不同语言的 ClassObject
。有点类似于 Thift
。所以一开始我们需要的是 ProtocolBuffer编译器
。
下载ProtocolBuffer编译器
下载地址 根据自己所使用的系统版本,下载对应的编译器。 下载完成以后,进入 protoc-3.7.1-osx-x86_64/bin
运行 ./protoc --version
如果能够打印版本号则说明安装成功。
编写简单的proto文件
现在开始尝试生成类似于以下 Java
类
1 | public class User { |
SpringCloud介绍
Redis 集群部署方式
总览
使用的 Redis
版本:4
通常来说,一个小型的项目一台 redis
服务实例即可满足需求,但是当系统很大的时候,客户端读写频繁,一台机器很容易就成为性能和内存的瓶颈,这时候就需要使用集群来拓展性能了。 redis
集群有两种方式:
全量复制
redis
在复制模式下被分为两类数据库:主数据库和从数据库。一个主数据库可以拥有多个从数据库,但是一个从数据库则只能拥有一个主数据库。当主库数据发送变化时,redis
会将数据自动同步到多个从数据库中去。 在 redis
数据库中使用复制功能很简单,只需要在从数据库的配置文件中加入以下配置即可实现:
ps:以下配置是 Redis4 的配置,在以前版本需要查看配置文件的配置方式。
1 | replicaof 192.168.1.129 6379 # 配置主数据库链接信息 |
Redis 持久化机制
总览
redis
数据库,可以直接用来当数据库使用,也可以当系统的缓存使用。但是 redis
大部分数据是存储在内存中的,当服务掉线重启,会造成数据的丢失。当然,redis
是有持久化线程的,我们可以利用这个持久化服务来做数据的持久化,这样当 redis
重启的时候,即可从硬盘重新读取数据,然后进行数据的恢复。 redis
的持久化方式有两种:
执行过程
redis
的 RDB
持久化是通过快照完成的。当符合一定条件的时候,redis
可以将目前的数据生成一份副本存储在硬盘。 redis
执行快照的一句有下面几种:
- 根据配置的规则
- 用户执行
SAVE
或BGSAVE
命令 - 执行
FLUSHALL
命令 - 执行复制时
配置规则
redis
可以根据用户在配置文件中配置的规则进行定时,定量的持久化。在 redis
的 conf
文件夹中配置如下:
1 | save 900 1 # 表示900秒以内有一个或以上的简直更改时进行快照 |