西维蜀黍

【Engineering】连接池(Connection Pool)

Configs

Unused timeout / IdleTimeout

为了让 middleware(比如 Redis)主动清理长时间空闲的客户端连接,回收资源,您可以设置timeout参数来限制客户端连接的空闲时间。

默认设置下,即使某个客户端已经空闲了很长时间,Redis也不会主动断开与该客户端的连接。但在业务核心应用中,建议配置timeout参数以使Redis具有主动回收资源的能力。否则,如果客户端出现异常,连接池资源将无法及时回收,可能因空闲连接占满连接池导致服务崩溃。核心应用出现这样的问题可能引发整个业务的混乱,后果严重。

timeout参数值的取值范围为[0,100000],默认为0(表示无限制),单位为秒(s)。在实际运行中,为了提高性能,Redis不一定会精确地按照timeout参数值的时间来断开符合条件的空闲连接,例如设置timeout参数值为10s,但空闲连接可能在12s后,服务器中新增很多连接时才会被断开。如需降低这个延迟,可适当增大hz参数的值,提高负责断开超时连接等定时任务的运行频率。

Connection timeout / PoolTimeout

Specifies the interval, in seconds, after which a connection request times out and a ConnectionWaitTimeoutException is thrown.

This value indicates the number of seconds that a connection request waits when there are no connections available in the free pool and no new connections can be created. This usually occurs because the maximum value of connections in the particular connection pool has been reached.

  ...


【MySQL】Connections Number Setting

MySQL 当前允许最大并发连接数(max connection)

max connection is a threshold specified in MySQL: the maximum permitted number of simultaneous client connections (if exceed, apps will get “Too many connections” error from MySQL).

If clients encounter Too many connections errors when attempting to connect to the mysqld server, all available connections are in use by other clients.

The permitted number of connections is controlled by the max_connections system variable. To support more connections, set max_connections to a larger value.

Command-Line Format --max-connections=#
System Variable max_connections
Scope Global
Dynamic Yes
SET_VAR Hint Applies No
Type Integer
Default Value 151
Minimum Value 1
Maximum Value 100000

mysqld actually permits max_connections + 1 client connections. The extra connection is reserved for use by accounts that have the CONNECTION_ADMIN privilege (or the deprecated SUPER privilege). By granting the privilege to administrators and not to normal users (who should not need it), an administrator can connect to the server and use SHOW PROCESSLIST to diagnose problems even if the maximum number of unprivileged clients are connected.

查看 MySQL 的最大并发连接数设置:

$ mysql –u root –p
mysql> SHOW VARIABLES LIKE 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 151   |
+-----------------+-------+

修改

Approach 1 - via Command

You can change the setting to e.g. 200 by issuing the following command without having to restart the MySQL server (obviously it will only work if the user you are logged in as has sufficient permissions to do this):

set global max_connections = 200;

This will take effect immediately, but will be forgotten the next time MySQL is restarted. To make the change permanent you need to edit the my.cnf configuration file.

Approach 2 -Via Config

$ vi /etc/my.cnf

There will be a section that looks like this: (may be slightly different)

[mysqld]
local-infile=0
datadir=/var/lib/mysql
user=mysql
symbolic-links=0

max_connections = 100

Save the changes and type the following to restart mysqld:

$ /etc/init.d/mysqld restart

You will see:

Stopping mysql: [ OK ]
Starting mysql: [ OK ]

MySQL 同时被使用的连接数的历史最大值(max used connection)

max used connection is the maximum number of connections that have been in use simultaneously since the server started.

mysql> show global status like 'Max_used_connections';
+----------------------+-------+
| Variable_name    | Value |
+----------------------+-------+
| Max_used_connections | 2   |
+----------------------+-------+
1 row in set (0.00 sec)
  ...


【Redis】查看连接信息

查看 Redis 当前连接数/最大连接数

127.0.0.1:6379> info clients
#Clients
connected_clients:621
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
127.0.0.1:6379>
方法2:config get maxclients 可以查询redis允许的最大连接数

127.0.0.1:6379> CONFIG GET maxclients
    ##1) "maxclients"
    ##2) "10000"

修改 Redis 最大连接数

方法1

在2.6之后版本,可以修改最大连接数配置,默认10000,可以在redis.conf配置文件中修改

...
# maxclients 10000
...

方法2

config set maxclients num 可以设置redis允许的最大连接数

127.0.0.1:6379> CONFIG set maxclients 10
OK
127.0.0.1:6379>

启动redis.service服务时加参数–maxclients 100000来设置最大连接数限制

方法3

启动redis.service服务时加参数–maxclients 100000来设置最大连接数限制

$ redis-server --maxclients 100000 -f /etc/redis.conf
  ...


【Redis】设置密码

设置密码

$ redis-cli -h 1.1.1.1 -p 11299
1.1.1.1:11299> config set requirepass "<your password>"

如果设置了密码,但是没有输入密码,在get时,就会出现下面错误

$ redis-cli -h 1.1.1.1 -p 11299
1.1.1.1:11299> get s
(error) NOAUTH Authentication required.

验证密码

密码验证成功

1.1.1.1:11299> auth <your password>
OK
  ...


【Performance】Linux 性能问题调优 - I/O

查看 I/O

如果CPU利用率不高,但是系统的Throughput和Latency上不去了,这说明我们的程序并没有忙于计算,而是忙于别的一些事,比如IO。(另外,CPU的利用率还要看内核态的和用户态的,内核态的一上去了,整个系统的性能就下来了。而对于多核CPU来说,CPU 0 是相当关键的,如果CPU 0的负载高,那么会影响其它核的性能,因为CPU各核间是需要有调度的,这靠CPU0完成)

网络

Refer to https://swsmile.info/post/performance-network-diagnose/.

iostat

iostat是I/O statistics(输入/输出统计)的缩写,iostat主要用于监控系统设备的IO负载情况,iostat首次运行时显示自系统启动开始的各项统计信息,之后运行iostat将显示自上次运行该命令以后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。

  ...


【MySQL】学习

MySQL 的功能模块

下面我给出的是 MySQL 的基本架构示意图,从中你可以清楚地看到 SQL 语句在 MySQL 的各个功能模块中的执行过程。

大体来说,MySQL 可以分为 Server 层和存储引擎层两部分。

  ...


【Distributed System】架构学习

基本概念

包括:系统与子系统、模块与组件、框架与架构。

系统与子系统

我们先来看维基百科定义的“系统”。系统泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体。它的意思是“总体”“整体”或“联盟”。

我来提炼一下里面的关键内容:

  • 关联:系统是由一群有关联的个体组成的,没有关联的个体堆在一起不能成为一个系统。例如,把一个发动机和一台 PC 放在一起不能称之为一个系统,把发动机、底盘、轮胎、车架组合起来才能成为一台汽车。
  • 规则:系统内的个体需要按照指定的规则运作,而不是单个个体各自为政。规则规定了系统内个体分工和协作的方式。例如,汽车发动机负责产生动力,然后通过变速器和传动轴,将动力输出到车轮上,从而驱动汽车前进。
  • 能力:系统能力与个体能力有本质的差别,系统能力不是个体能力之和,而是产生了新的能力。例如,汽车能够载重前进,而发动机、变速器、传动轴、车轮本身都不具备这样的能力。
  ...


【Distributed System】无服务器(Serverless)

什么是无服务器计算?

“无服务器”是云计算中资源抽象的极致体现。从它的命名上你就可以看出,所谓“无服务器”就是想让用户感觉不到服务器的存在,这是因为有一朵巨大的云在底层进行着支撑。这样你可以完全专注于业务逻辑的编写,而不再关心任何基础设施。

我们在前面课程的讨论中,其实已经接触到了一些广义上的无服务器 PaaS 服务,比如第 13 讲中的无服务器查询服务和第 14 讲中的无服务器容器服务。甚至第 9 讲中的对象存储服务,它理论上来说也是符合无服务器特征的,因为你不用关心究竟是什么样的机器和多少机器在背后支撑它。

今天我们要来专门讨论的,是经典的无服务器计算服务(Serverless Computing)。“无服务器”这个名称,就是从这种灵活的计算服务起源的。

如果把无服务器计算和容器类服务一起比较的话,这两种云上计算类服务有着共同的优势和特点,比如说,它们都支持细粒度封装和易于大规模扩展。但这两者也有很不一样的地方。

如果说容器是给予了我们很大的定制空间,让你更加容易地按照自己的需要,来进行应用程序的拆分和封装;那么无服务器则是完全屏蔽了计算资源,它是在真正地引导你不再去关心底层环境,你只要遵循标准方式来直接编写业务代码就可以了。

而且在粒度上,无服务器会允许你拆分得更细致、更轻量。你甚至可以把每一个具有独立功能的函数,来作为一个单独的服务进行部署和运行。这也是为什么,在有些云计算的分类方法下,无服务器计算能够单独“开宗立派”,被称为**函数即服务(Function-as-a-Service,FaaS)**的原因。

  ...


【Network】网络测速工具 - iperf3

iperf3

iperf is a tool for active measurements of the maximum achievable bandwidth on IP networks. It supports tuning of various parameters related to timing, protocols, and buffers. For each test it reports the measured throughput / bitrate, loss, and other parameters.

Usage

# server
$ iperf3 -s -p 1020

# client
iperf3 -c 127.0.0.1 -p 1020
Connecting to host 127.0.0.1, port 1020
[  5] local 127.0.0.1 port 51841 connected to 127.0.0.1 port 1020
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  5.51 GBytes  47.3 Gbits/sec
[  5]   1.00-2.00   sec  5.57 GBytes  47.8 Gbits/sec
[  5]   2.00-3.00   sec  5.44 GBytes  46.7 Gbits/sec
[  5]   3.00-4.00   sec  6.23 GBytes  53.5 Gbits/sec
[  5]   4.00-5.00   sec  6.17 GBytes  53.0 Gbits/sec
[  5]   5.00-6.00   sec  6.11 GBytes  52.5 Gbits/sec
[  5]   6.00-7.00   sec  6.23 GBytes  53.5 Gbits/sec
[  5]   7.00-8.00   sec  6.14 GBytes  52.7 Gbits/sec
[  5]   8.00-9.00   sec  6.17 GBytes  53.0 Gbits/sec
[  5]   9.00-10.00  sec  6.13 GBytes  52.6 Gbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.00  sec  59.7 GBytes  51.3 Gbits/sec                  sender
[  5]   0.00-10.00  sec  59.7 GBytes  51.3 Gbits/sec                  receiver

iperf Done.
  • -p [port]:指定端口
  • -u:使用UDP
  • -b [target bitrate] :target bitrate in bits/sec (0 for unlimited) (default 1 Mbit/sec for UDP, unlimited for TCP)
  • -t [duration]:time in seconds to transmit for (default 10 secs)
  ...


【Golang】使用 - JSON序列化与反序列化

struct转JSON

我们可以在struct的attribute后指定该struct被序列化成JSON后的key的值,这被称为Struct Tag。

Struct tag 可以决定 Marshal 和 Unmarshal 函数如何在序列化和反序列化数据时,JSON key的值。

如果没有指定,则取该attribute对应全小写字符串作为key的值。

package main

import (
	"encoding/json"
	"fmt"
)

type User struct {
	UserName string `json:"username"`
	NickName string `json:"nickname"`
	Age      int
	Birthday string `json:"birth"`
	Sex      string
	Email    string
	Phone    string
}

/*结构体转json*/
func testStruct() {
	user1 := &User{
		UserName: "user1",
		NickName: "上课看似",
		Age:      18,
		Birthday: "2008/8/8",
		Sex:      "男",
		Email:    "mahuateng@qq.com",
		Phone:    "110",
	}

	dataBytes, err := json.Marshal(user1)
	if err != nil {
		fmt.Printf("json.marshal failed, err:", err)
		return
	}

	fmt.Printf("%s \n", string(dataBytes))
}

func main() {
	testStruct()
	fmt.Println("----")
}

//output
{"username":"user1","nickname":"上课看似","Age":18,"birth":"2008/8/8","Sex":"男","Email":"mahuateng@qq.com","Phone":"110"} 
----
  ...