MySQL 体系结构
从图我们可以看出,MySQL 有如下几部分组成:
连接池组件
管理服务和工具组件
SQL 接口组件
查询优化组件
优化器组件
缓冲组件
插件式存储引擎
物理文件
需要注意存储引擎是基于表的而不是库,比如我们可以在建表的时候为表指明存储引擎。
MySQL 存储引擎
常见存储引擎
InnoDB MySQL 5.5.8 版本之后的默认存储引擎,事务性,行锁,支持外键。
MyISAM 存储引擎不支持事务、表锁,支持全文索引,主要面对一些 OLAP 数据库应用。MySQL 5.5.6 版本之前的默认存储引擎。
NDB 存储引擎是一个集群存储引擎。
Memory 存储引擎将表
有时候我们需要在短时间内往 redis 里插入大量的数据,我们如果单条单条的出入会浪费很多时间和服务器资源,我们可以使用管道来实现快速的插入。
netcat
我们把需要插入 redis 的数据创建为如下的一个命令集文件
set key1 val1
set key2 val2
...
set key3 val3
我们使用如下命令执行数据导入
> $ cat /tmp/test|nc localhost 6379
+OK
+OK
+OK
pipe mode
使用 netcat 并不是一个可靠地方式,因为用netcat进行大规模插入时不能检查错误。从Redis 2.6开始redis-cli支
管道
redis 是基于客户端-服务端模型以及请求/响应协议的TCP服务。也就是说每次请求都需要建立 TCP 连接并发送命令和接受返回数据。所以当我们有大量的命令需要执行的话那么就需要花费太多的时间在 TCP 连接建立上。
依次 TCP 连接之后可以执行多条命令这样就可以提升命令执行速度,减少不必要的消耗,redis 就是通过支持管道技术来实现的。
管道示例如下:
> $ (printf "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379
+PONG
+PONG
+PONG
发布订阅
发布订阅实现了不同的客户端对不同的频道发送
事务
redis 中和事务相关的命令有四个:MULTI EXEC DISCARD WATCH,MULTI 用于开始一个事务,EXEC 用于提交事务,DISCARD WATCH 可以为事务提供乐观锁(后面会讲具体使用)。
事务的流程:客户端连接服务器,MULTI 命令开启一个事务,然后客户端可以向服务器发送任意多条命令,但是命令不会立即执行,直到我们发送EXEC命令,所有命令才会根据发送的顺序依次执行。当我们在执行EXEC之前如果想要停止事务可以通过发送DISCARD来终止事务。
redis 事务有如下特性:
事务是一个隔离操作,事务中的命令会按顺序执行,事务执行过程中不会被其他客户端打断。
redis 是内存性 key-value 数据库,所以 redis 的存储数据的大小受内存的限制,redis 默认是不会删除 key 的(过期的可以除外),当内存使用完的时候,新的写入操作就会返回错误。但是 redis 支持配置回收策略来实现数据过期,Redis 只支持 LRU 回收算法(memcache也是默认算法)。
maxmemory
maxmemory 用来配置 Redis 存储数据的内存大小限制,如果我们要使用 redis 实现 LRU 算法,并限制数据的多少可以通过这个配置来实现。
示例
maxmemory 1g # 限制 1G 内存大小
设置maxmemory为0代表没有内存限
redis 的 string 类型是支持过期设置的,默认是永不过期的。
Redis 设置过期
redis 中设置设置 key 过期有3中方式
第一种在设置值的时候指定过期时间
Set 命令格式
SET key value [EX seconds] [PX milliseconds] [NX|XX]
EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
PX millisecond :设置键的过期时间为 millisecond 毫秒。 3. SET key value PX m
information_schema
MySQL 自带一个数据库 information_schema ,这个数据库用于记录 MySQL 数据库的基本信息,比如数据库名,数据库的表,表栏的数据类型与访问权限等。
mysql> use information_schema;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql>
Go 语言的可移植性
Java 平台可移植性是众所都知的,Java 的可移植性依赖于其虚拟机 JVM,Java 实现了对不同平台的 JVM 的支持,那么一份 Java 代码就可以在各个平台上运行。而 Go 语言的可移植性也是依赖于其 runtime,runtime 去对接操作系统层,用户代码在 runtime 中运行,用户代码就不用去关心平台问题。
查看 Go 支持的OS和平台:
> $ go version
go version go1.11 darwin/amd64
liushuai@liushuaideMacBook-Pro ~/Documents/goProject/src
我们写一个关于系统信号量的程序并用 go run 调试。
测试代码如下:
package main
import (
"os"
"os/signal"
"fmt"
"syscall"
)
func main() {
sig := make(chan os.Signal)
signal.Notify(sig, syscall.SIGUSR2)
for {
select {
case s := <-sig:
fmt.Println(s.String())
}
我们经常需要让主 goroutine 处于永久阻塞状态,这样其他的 gorotine 就可以一直运行处理信息。下面我总结了几种可以实现永久阻塞的方法,其中大部分实例代码无法直接运行,因为 Go runtime 会检查所有 goroutine 并提示所有的 goroutine 都处于 deadlock,在实际使用中,我们添加具体的业务 goroutien 就可以运行了。
死循环
说到永久阻塞第一个想到的应该就是死循环。
package main
func main() {
for {}
}
死循环虽然可以实现永久阻塞,但是对于 Go 而言,for 死循环所在的 goroutine 还是