使用C++自编译opencv源码给python扩展CV2模块

公司最近做起了无人商店项目,需要识别人脸.人脸识别采用了海康的摄像头直接从摄像机抓图来自己识别人脸!先使用了标准的OpenCV   python库,最后效果不理想达不到可以需求的识别速度,希望能提高!
于是希望通过自己编译opencv的源码添加更多功能编译成pyd文件供python调用!
参考文档  https://docs.opencv.org/3.3.1/d3/d52/tutorial_windows_install.html  编译文档 https://docs.opencv.org/3.3.1/d5/de5/tutorial_py_setup_in_windows.html
各种安装包如下

第一步安装python3
64位系统 下的Python3.5。python3.5、pip为必备前提。python可在官网下载:https://www.python.org/downloads/windows/,建议使用exe installer,pip会随之安装。环境变量中加入python安装路径,
安装numpy,打开CMD窗口使用pip安装

pip install numpy
第二步安装vs2015_x64位的编译环境,安装选项如下,然后一路NEXT安装通过

第三步安装  cmake,cuda, doxygen的exe安装包,完成后重启机器,让所有的安装都生效
第四步 源码准备
双击opencv-3.4.0-vc14_vc15.exe 将源码解压到D盘根目录

在sources目录下新建一个dep文件夹,将eigen  openexr  TBB的源码解压到这个目录中

把OpenBLAS已经编译完成的压缩包 OpenBLAS-v0.2.19-Win64-int32.zip 解压到D盘根目录

第五步 启动cmake配置编译的参数

第三步选择刚OpenBLAS压缩包解压的路径,引入包和dll文件
第四步选择配置的时候一定要记得选着VS的版本和当前安装版本一致,否者会出现找不到编译器的异常
第五步检查生成代码完成后,直接点击第六步,通过VS打开项目
将debug改成Release 模式

找到INSTALL 鼠标右键选择菜单的生成按钮,大约几个小时候编译完成!编译完成后我们就可以在
python的安装目录下Python\Python35\Lib\site-packages找到生成好的PYD文件

此时我们就可以import CV2这个python模块 不报错就表示引起包成功

Docker 命令集

寻找网络镜像命令
docker search centos
[root@test ~]# docker search centos
名字 描述 下载次数 是否官方 是否是Dockerfile构建的
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMAT
docker.io docker.io/centos The official build of CentOS. 3301 [OK]
下载镜像
docker pull centos
查看镜像
docker images
删除镜像
docker rmi
容器命令
启动容器
docker run –name -h hostname
启动容器2
docker start CONTAINER ID
停止容器
docker stop CONTAINER ID
查看容器
docker ps -a
进入容器
docker exec | docker attach
删除容器
docker rm
进入后台运行容器
docker attach 68e5c66ee5c9 退出自动停止运行容器
进入容器
docker run –name mydocker -it docker.io/centos /bin/bash
-d 进入后台运行
–run 运行
–name 指定名字
-i 输入终端打开
-t 开一个伪终端
进入容器不退出
1、进入容器
docker run –name mydocker -it docker.io/centos /bin/bash
2、退出
3、启动容器
docker ps -a查询ID号
docker start ID号
4、获取Pid号
docker inspect –format “{{.State.Pid}}” 68e5c66ee5c9
5、进入容器而不退出
nsenter –target 19205 –mount –uts –ipc –net –pid 退出不停止运行容器
如果没有这个命令,需要安装util-linux包 nsenter
6、懒人写法
nsenter –target `docker inspect –format “{{.State.Pid}}” ID` –mount –uts –ipc –net –pid
docker 网络访问
docker run -P
-P 随机映射
-p hostport:containerPort
-p ip:hostPort:containerPort
-p ip::containerPort
-p hostPort:containerPort
-p hostPort:containerPort
数据卷管理
docker
-v /data
-v /src:/dsrc
-v /src:/src:ro
容器的制作
docker commit -m “my nginx” f443e801f545 shijia/my-nginx:v1
Docker file 的方式构建docker镜像
FROM 他的妈妈是谁(基础镜像)
MAINTAINER 告诉被人,你创造了他(维护者信息)
RUN 你想让他干啥(把命令前面加上RUN)
ADD 相当于cp命令(COPY文件,会自动解压)
WORKDIR 相当于cd命令(当前工作目录)
VOLUME 给我一个放行李的地方(目录挂载)
EXPOSE 我要打开的门是啥(端口)
RUN 奔跑吧,兄弟!(进程要一直运行下去)
Docker 案例
vim /opt/docker-file/nginx/Dockerfile
# This is My first Dockerfile
# Version 1.0
# Author : Shijia Zhang
#Base images
FROM centos
#MAINTAINER
MAINTAINER ShiJia Zhang
#ADD
ADD pcre-8.37.tar.gz /usr/local/src
ADD nginx-1.9.3.tar.gz /usr/local/src
#RUN
RUN yum -y install wget gcc gcc-c++ make openssl-devel
RUN useradd -s /sbin/nologin -M www
#WORKDIR
WORKDIR /usr/local/src/nginx-1.9.3
#RUN
RUN ./configure –prefix=/usr/local/nginx –user=www –group=www –with-http_ssl_module –with-http_stub_status_module –with-pcre=/usr/local/src/pcre-8.37 && make && make install
RUN echo “daemon off;” >> /usr/local/nginx/conf/nginx.conf
ENV PATH=/usr/local/nginx/sbin:$PATH
EXPOSE 80
CMD [“nginx”]
运行Dockerfile
docker build -t nginx-file:v1 /opt/docker-file/nginx/
其他命令
docker run -it –rm stree –cpu 1
–rm 容器运行完即可删除
–cpu 指定分多少颗CPU

Python快速搭建自动回复微信公众号

安装Python库

通过 pip 安装 wechat-python-sdkRequests 以及 Tornado  mongdb的库和安装mongodb并且启动服务(http://www.cnblogs.com/shanyou/archive/2012/07/14/2591838.html)

pip install tornado
pip install wechat-sdk
pip install requests
pip install pymongo

订阅号申请

要搭建订阅号,首先需要在微信公众平台官网进行注册,注册网址: 微信公众平台
目前个人用户可以免费申请微信订阅号,虽然很多权限申请不到,但是基本的消息回复是没有问题的。

下载后台的代码并启动服务端

完整的公众号代码 GitHub 下载地址:green
 
解压后在根目录添加conf.json的文件内容如下:
{
“token”: “weixin”,
“appid”: “wxdf3b580aaf7712a433338a”,
“secret”: “424e8cdb82422291d42312312313c313abb5175530”,
“mode”: “normal”,
“mongo_db”: “green”,
“max_host_count”: 5,
“auto_reply”: “yes”,
“tuling_key”: “d0fbe02cb1775baa922234d8b7222716aa15933”,
“tuling_url”: “http://www.tuling123.com/openapi/api”
}
这里就是启动的配置文件,注意需要填写你自己公众号的appid  secret 来填写 和图灵的tuling_key(需要自己注册账号申请KEY)
通过python  main.py   命令启动我们的服务端

服务器接入

具体的接入步骤可以参考官网上的接入指南
本订阅号的配置为:
服务器配置
配置里的URL为服务器提供订阅号后台的url路径,本文用到的源代码配置的是 http://server_ip/wx 其中 server_ip 是运行源代码的主机的公网ip地址。
(只能是80端口,不能使用其他端口,一定要带/WX的后缀路径)
Token 可以设置为任意字符串(这里和上面的配置文件中的weixin对应)。
EncodingAESKey 可以选择随机生成。
消息加密方式可以设置为比较简单的明文模式
 
 

mysql读书笔记

闲来无事对MYSQL的读书笔记进行了一下整理,记录下来。难道真的是人老了,记性越来越差了。
数据库的基本概念
data 数据
database 数据库
DBMS 数据库管理系统
DBS 数据库系统
sql 是结构化查询语言
##########################################################################################################################
数据类型种类
整形: 可以有十进制和十六进制表示
符点形: 浮点数由一个数字加一个小数点再加上一个数字组成。两个数字序列不能同时为空。
字符串: 由单引号或者双引号括起来的字符或者数字,字符串中要用转义字符才能表示的特殊符号。
NUUL值: 是一种无类型的值,表示“空,什么也没有”。
日期和时间的值:列如 2005-05-30 12:30:25 日期是按年-月-日
_##########################################################################################################################
数值类型
TINYTIN 非常小的整数 BIGINT 大整数
SMALLINT 较小的整数 FLOAT 单精度浮点数
MEDIUMINT 中等大小的整数 DOUBLE 双精度浮点数
INT 标准整数 DECIMAL 一个串的浮点数
CHAR 定长字符串 VARCHAR 可变长字符串
TINYBLOB 非常小的BLOB BLOB 小BLOB
MEDIUMBLOB中等BOLB LONGBLOB 大BLOB
TINYTEXT 非常小的文本串 TEXT 小文本串
MEDIUMTEXT中等文本 LONGTEXT 大文本串
ENUM 枚举:列可赋予某个枚举成员
SET 集合:列可赋予多个集合成员
##########################################################################################################################
not null 非空 primary key 主键 auto_increment 自增
常见的完整性约束
primary key 主码约束(主键) 主码就是主关键字,能唯一标示字段属性
unique 唯一约束 在一个字段或者一组字段里数据与表中其它行的数据相比是唯一的
not null 非空值约束
auto_increment 整数列自增1
default_value 默认值约束
##########################################################################################################################
mysql -h主机名 -u用户名 -p密码 //mysql登陆运行命令
######mysql输入一个语句结尾时,末尾要有;号。->意为本语句没有输完 等待继续输入。c用来取消输入。
auto_increment 自动标识列
对于想使用此属性的列应该定义为NOT NULL,并定义为PRIMARY KEY 或者定义为UNIQUE键。
unsigned无符号,此属性禁用负值,是将数值的取值范围从零开始,即前移了取值范围而已.
##########################################################################################################################
DML数据操作语言
select 查询
insert 插入
update 修改
delete 删除
##########################################################################################################################
DCL数据控制语言
grant 控制存取许可
revoke 存取权限
##########################################################################################################################
ddl数据定义语言
create table 创建数据表
create database 创建库名
drop table 数据库对象
alter table 定义其列
##########################################################################################################################
use 库名 选择使用数据库 例如:use book;
##########################################################################################################################
创建数据库
create database 库名; 创建一个指定名称的数据库
例如:create database book; 创建了一个名为book的数据库
##########################################################################################################################
删除数据库或表操作
drop table 表名 删除表 drop table if exists badbird;加if exists 删除不存在表名不会出错
drop database 库名 删除库 同上加if exists不会出错
##########################################################################################################################
显示结构操作
database 表名
desc 表名
##########################################################################################################################
show用法
show tables或show tables from database_name like; — 显示当前数据库中所有表的名称。
show databases; — 显示mysql中所有数据库的名称。
show columns from table_name from database_name;
show columns from database_name.table_name; — 显示表中列名称。
show grants for user_name; — 显示一个用户的权限,显示结果类似于grant 命令。
show index from table_name; — 显示表的索引。
show status; — 显示一些系统特定资源的信息,例如,正在运行的线程数量。
show variables; — 显示系统变量的名称和值。
show processlist; — 显示系统中正在运行的所有进程,也就是当前正在执行的查询。大多数用户可以查看他们自己的进程,但是如果他们拥有process权限,就可以查看所有人的进程,包括密码。
show table status; — 显示当前使用或者指定的database中的每个表的信息。信息包括表类型和表的最新更新时间。
show privileges; — 显示服务器所支持的不同权限。
show create database database_name;– 显示create database 语句是否能够创建指定的数据库。
show create table table_name; — 显示create database 语句是否能够创建指定的数据库。
show engies; — 显示安装以后可用的存储引擎和默认引擎。
show innodb status; — 显示innoDB存储引擎的状态。
show logs; — 显示BDB存储引擎的日志。
show warnings; — 显示最后一个执行的语句所产生的错误、警告和通知。
show errors; — 只显示最后一个执行语句所产生的错误。
show [storage] engines; –显示安装后的可用存储引擎和默认引擎。
##########################################################################################################################
select用法
select prod_uame from products; –查询从products表中检索出名字为prod_nume的列(无序排列)
select prod_uame,user, password from products; –查询从products表中检索出名字为prod_nume,user, password的列
select * from products; –查询从products表中检索出全部列(*表示匹配所有的)
select distinct prod_id from products; –查询从products表中检索出名字为prod_id的列(只返回唯一的prod_id行)
select prod_uame from products limit 5; –查询从products表中检索出名字为prod_nume的列不超过5行(无序排列)
select prod_uame from products limit 5,6; –查询从products表中检索出名字为prod_nume从行5开始共6列(行从0开始计算)
select prod_uame from products limit 6 offset 5; –查询从products表中检索出名字为prod_nume从行5开始共显示6列(行从0开始计算)
select products.prod_uame from database.products; –查询从database库中products表中检索出名字为prod_nume的列(无序排列)
select prod_price from products order by prod_price DESC limit1; –查询从products表中检索出名字为prod_price的列最大的值(无序排列)
select prod_price from products where prod_price=2; –查询从products表中检索出名字为prod_price的列中值为2的列(无序排列)
##########################################################################################################################
更改表结构操作
语法:alter table 表名 action;
说明:action 可以是如下语句:
add 列名 <建表语句> [first | after 列名]
add primary key (列名)为表添加一个主键,如果主键已经存在,则出现错误
alter 列名 set default 默认值 可以更改指定列默认值
———————————————————-
later table 表名 add 插如列的名 varchar(属性) first(之前)|after(之后) 增加列名
change 旧列名 新列名 <建表语句> [first | after 列名]
可以更改列类型和列名称,如果原列的名字和新列的名字相同,则change和modify的作用相同
———————————————————–
modify 列名 <建表语句> [first | after 列名]
更改列属性:alter table badbird(表名) badtitle(列) modif varchar(属性);
更改列名:alter table badbird(表名) change badtitle(列) bad_sad(改的名) varchar(属性) not null(no 空);
drop 列名 //可以删除一列
drop primary key //可以删除主键
drop index index_name; //可以删除索引
删除列:alter table badbird(表名) drop badtitle;
rename as 新表名 //可以将表名更改
更改表名:alter table badbird(表名) rename badwolf(表名);
##########################################################################################################################
插入记录操作
语法:
insert into 表名(字段名,字段名, … ) values(字段值,字段值,…);
例如:insert into badwolf (bad_id,bad_name) values(3,’badbird’); 插入
如果表名后面没写字段名,则默认是向所有的字段添加值,另外字符串值应该用‘ ’或“ ”引号括起来
多条添加:insert into badwolf values(1,’badbird’),(2,’badbird’),(4,’badbird’);
更改记录操作
语法:
update 表名 set 列名=数据值 where 子句;
例如:update badwolf(表名) set bad_name(列名)=’badwolf’;
——————————————————————
where 子句是判断语句,用来设定条件,限制只更新匹配的行,如果不带where子句,则更新所有行数据
删除记录操作 语法: delete from 表名 where子句;
例如:delete from badwolf(表明) where bad_id=2; 判断删除所有id=2的值 判断条件可以附加
null和not null
缺省为null(空)即插入值时没有在此字段插入值,默认为NULL值.
如果指定了NOT NULL,则必须在插入值时在此字段添入值,不允许插入NULL值。
default 通过此属性来指定缺省值,如果没有添加值则默认此值。
zerofill 前导零填充数值类型以达到列的显示宽度。
例如:create table badbird(
bad int,
bad unsigned,(无符号,将数值的取值范围从零开始)
bad unsigned zerofill,(无符号,将数值的取值范围从零开始|前导零填充数值类型以达到列的显示宽度)
bad unsigned zerofill,(无符号,将数值的取值范围从零开始|前导零填充数值类型以达到列的显示宽度)
insert into badbird values(10,10,10,10);
结果:10,10,0000000010,0000000010。 整形获取值为10,从零开始获取也是10,从零开始以0做填充
insetr into badbird values(-10,-10,-10,-10);
结果:-10,0,0000000000,0000000000。整形获取值为10,从零开始,从零开始以0做填充
insert into badbird values(2147483647,2147483647,2147483647,2147483647)
结果:2147483647,2147483647,2147483647,2147483647。整形获取值为10,从零开始获取也是10,从零开始以0做填充 无填充
insert into badbird values(3004005006,3004005006,3004005006,3004005006);
结果:2147483647,3004005006,3004005006,3004005006。int标准整形最大值
字符串列类型的属性
binary
使用此属性可以使列值作为二进制串处理,即比较和排序时区分大小写。
NOT 和NOT NULL
同数值型功能相同
default
同数值型功能相同
日期和时间列表
date YYYY-MM-DD 格式表示日期值 3字节
time hh:mm:ss 格式表示时间值 3字节
datetime 时间-日期 8字节
timestamp 时间戳 4字节 时间戳=mysql的时间戳是1970年到至今的豪秒数
tyar YYYY年份 1字节
now() 函数自动获取本地时间
mysql算术运算符
+加 -减 -负 *乘 /除 %取余
如果第一位是数字的字符串被用于一个算数运算中,那么它被转换为这个数字的值。
如果一个包含字符和数字混合的字符串不能被正确的转换为数字,那么它被转换成0。
##########################################################################################################################
mysql比较运算符
and 并且
or 或
= 两个操作数相等 为true
!=|<> 两个操作数不等 为true
< <= > >= 不用解释你要不知道我也没办法
in 如果a为b1,b2中的任何一个 为true
between 如果A的值 在b1与b2之间包括等于b1b2 为true b1必须比b2大
like 模式匹对 如果a匹对b 为true
notlike 模式匹对 如果a不匹对b 为true
regexp 同like
not regexp 同notlike
<=> a<=>b 如果两者操作数相同 即使null 为true
is null 如果操作数为null 为true
is not null 如果操作数不为空 为true
再次声明mysql 不区分大小写
%号表示以A开头 任意后缀结尾
_号表示A开头 后缀任意字
##########################################################################################################################
查询记录操作
语法:
select 字段名,字段名, … (*) from 表名 where 子句 group by子句having子句 order by子句 limit子句 desc(asc)
group by子句是对匹配where子句的查询结果进行分组
having子句是对分组后的结果进行条件限制
order by子句是对查询结果结果进行排序,后面跟desc或asc。 
limit子句是对查询的显示结果限制数目
desc是将最终结果进行降序排列,asc是将最终结果进行升序。
例如:select * from badbird(表名) where fi=10条件;
##########################################################################################################################
MySQL数据库管理
数据库的启动与关闭,安全、访问控制和权限,数据库的备份与恢复,导入和导出记录
数据库管理员的职责
服务器的启动与关闭
用户帐户维护
日志文件维护
数据库的备份与拷贝
服务器的优化
数据库管理系统的软件更新
数据目录的安全性
服务器的安全性
灾难恢复
预防性维护
##########################################################################################################################
数据库的启动与关闭
1、数据库的启动:
方法1:使用service 命令启动MySQL
# service mysqld start // mysqld是MySQL的守护进程,通过运行它来启动MySQL服务。
方法2:使用mysqld脚本启动MySQL
# /etc/init.d/mysqld start
方法3:使用safe_mysqld实用程序启动MySQL服务,此方法可以使用相关参数
# safe_mysqld& //使用&符号将safe_mysqld放在后台运行。
2,校验MySQL是否被启动:
# service mysqld status //返回如下信息,表示已经启动
mysqld (pid 1663) is running… //1663是mysqld运行的进程号,可能根据不同系统运行的进程数量而不同
若需要重新启动MySQL可以使用如下命令之一:
# service mysqld restart
# /etc/init.d/mysqld restart
3、数据库的关闭:
可以使用如下命令之一:
# service mysqld stop
# /etc/init.d/mysqld stop
# /mysqladmin shutdown
##########################################################################################################################
######### MySQL管理 MySQL管理 MySQL管理 MySQL管理 MySQL管理 #####
######### MySQL管理 MySQL管理 MySQL管理 MySQL管理 MySQL管理 #####
######### MySQL管理 MySQL管理 MySQL管理 MySQL管理 MySQL管理 #####
##########################################################################################################################
一,修改root管理密码
方法1:
mysql>set password for ‘帐号’@‘主机’ = old_password(‘输入新密码’);
update mysql.user set password = old_password(‘输入新密码’) where host = ‘主机’ and user = ‘帐号’;
flush privileges;
方法2:
mysqladmin -u 用户 -p 旧密码 password ‘新密码’;
用户密码
对于MySQL密码可以使用PASSWORD()和ENCRYPT()函数进行加密
mysql>select PASSWORD(“alex”);
“23fc96e064be0017”
注:ENCRYPT()在Windows上不可用
方法3:
使用update语句和password()函数将root口令设置为crp。
mysql> update mysql.user set password=password(‘crq’) where user=’root’; //返回如下信息,表示授权表user修改成功
Query OK, 2 row affected (0.09 sec)
Rows matched:2 changed:2 warnings: 0
mysql> flush privileges; //此时即生效可以使用。注意:由此种方法是直接对授权表user进行修改,而服务器只有在启动时才会加载授权表中的权限设置,因此必须要使用客户端程序mysql环境下的flush privileges命令或使用管理工具mysqladmin的flush-privileges子命令通知服务器重新加载授权表。
##########################################################################################################################
二,改变数据库存储路径
在Window下,MySQL的所有数据库都保存在“%mysqlroor%data”目录下。
停止MySQL服务
修改%systemroor%my.ini文件
[mysqld]
datadir=D:/data
将原目录中的所有文件和文件夹内容,全部移动到新的目录D:/data目录中。
重启MySQL服务
##########################################################################################################################
三,修改MySQL字符集
找到MySQL配置文件my.ini,一般在C:windowmy.ini。
在my.ini文件里面加上“default-character-set=gbk #”或gb2312,utf8
重启MySQL服务
##########################################################################################################################
四,删除匿名用户:
myslq> delete from user where user=’ ‘;
//返回如下信息,表示匿名用户删除成功
Query OK, 2 row affected (0.03 sec)
##########################################################################################################################
五,添加新的用户权限:
使用grant语句用于授予用户权限,
语法:
GRANT priv_type[(column_list)][,priv_type[(column_list)]…]
ON {*.* | * | db_name.* | db_name.tabl_name | db_name}
TO user_name [IDENTIFIED BY ‘password’]
[,user_name [IDENTIFIED BY ‘password’]…]
[WITH GRANT OPTION]
##########################################################################################################################
六,创建新用户
制定用户名,最长允许为16个英文字符
制定允许该用户可以访问的数据库和表
制定允许该用户对数据库做什么的操作
制定允许该用户从哪些主机/IP进行远程连接
制定允许该用户对其他用户进行授权或取消授权
例如:添加一个可以从本地主机连接到MySQL服务器的超级用户crq,但是连接时必须使用口令crqpass
mysql> grant all on *.* tocrq@localhostidentfied by ‘crqpass’ with grant option;//返回如下信息,表明权限设置成功
Query OK, 0 rows affected (0.02 sec)
例如:使用同样的方法添加一个可以从其他任何地方连接到MySQL服务器的超级用户crq,但是连接时必须使用口令crqpass
mysql> grant all on *.* tocrq@’%’identified by ‘crqpass’ with grant option;
##########################################################################################################################
七,授予用户特定的权限:
使用grant语句添加一个可以从本地机连接的MySQL服务器的用户user1,并且只授予其针对sales数据库中employee表的select和insert权限。
mysql> grant select,insert on sales.employee touser1@localhostidentified by ‘user1pass’;
说明:使用:# mysql –u user1 –puser1pass 登录数据库以后可以做如下操作:
mysql> use sales; //打开sales数据库
mysql> show tables; //只能看到employee表
mysql> select * from employee; //可进行查看操作
mysql> insert into employee ……. //可进行插入操作。
##########################################################################################################################
八,撤销用户权限:
语法:REVOKE priv_type[(column_list)][,priv_type[(column_list)]…]
ON {*.* | * | db_name.* | db_name.tbl_name | db_name}
FROM user_name [,user_name…]
例如:撤消用户user1针对sales数据库中employee表的insert权限:
mysql> revoke insert on sales.employee fromuser1@localhost;
//返回如下信息,表明权限撤销成功。
Query OK, 0 row in set affected (0.00 sec)
##########################################################################################################################
九,权限更改何时生效
当mysqld启动时,所有的授权表内容被读进存储器并且从那点生效。
用GRANT、REVOKE或SET PASSWORD对授权表施行的修改会立即被服务器注意到。
如果你手工地修改授权表(使用INSERT、UPDATE等等),你应该执行一个FLUSH PRIVILEGES语句或运行mysqladmin flush-privileges告诉服务器再装载授权表,否则你的改变将不生效,除非你重启服务器。
##########################################################################################################################
十,权限更改的影响
当服务器注意到授权表被改变了时,现存的客户连接有如下影响:
表和列权限在客户的下一次请求时生效。
数据库权限改变在下一个USE db_name命令生效。
全局权限的改变和口令改变在下一次客户连接时生效。
##########################################################################################################################
十一, 数据库的备份与恢复
1、数据库的备份:
A、用mysqldump备份数据库:
语法: mysqldump [OPTIONS] database [table]
实例:
将数据库sales备份成sales_bak030630.sql文件。
# mysqldump –u root –p –opt sales > sales_bak030630.sql
//返回如下信息,表明备份成功
-rw-r–r– 1 root root 2296 Jun 29 23:30 sales_bak030630.sql
B、用直接拷贝的方法备份数据库:
不用mysqldump 来备份数据库或表的另一种方法是直接拷贝表文件。通常可利用像cp、tar 或cpio 这样的实用程序来进行。当使用直接拷贝备份( direct-copy backup)方法时,必须确保没有使用这些表。如果在拷贝一个表的同时服务器正在修改它,则拷贝无效。
确保拷贝完整性的最好方法是关闭服务器,拷贝文件,然后重新启动服务器。
2、数据库的恢复:
数据库系统出现崩溃时,应该使用最近的一次备份对数据库进行恢复,如果启用了更新日志,还需要重新执行更新日志中最近一次备份之后对数据库进行修改的任何查询,以尽可能将数据恢复到崩溃时刻所处的状态。
# mysql –u root –p sales < sales_bak030630.sql ########################################################################################################################## 优化表 在大多数情况下,优化表的做法很值得。当一个表被多次修改,那它的结构将很快变得支离破碎,其结果是导致性能的下降。这个时候可以使用OPTIMIZE TABLE 命令来刷新,清理出空间。 mysql>OPTIMIZE TABLE tablename;
##########################################################################################################################
导入和导出记录
INSERT语句不是向表中插入记录的唯一方法,MySQL还允许使用LOAD DATA INFILE 命令一次性插入多条记录。这个命令可以从文本文件读出原始数据(该文件可以放置在连接服务器上或者客户端),在列和行界定符号的基础上进行分析,然后自动产生INSERT 语句来向一个表写数据。
导入数据
默认情况下,MySQL认为数据文件是在服务器上,在LOAD DATA INFILE 语句中指定位置。
如果想要使用客户机上的数据,可以在语句中添加LOCAl关键字,告诉MySQL在客户机的文件系统上查找文件。
mysql>LOAD DATA LOCAL INFILE ‘c:data.txt’
INTO TABLE user
FIELDS TERMINATED BY ‘,’ LINES TERMINATED BY ‘n’;
最好在此之前加上如下命令
mysql>LOAD DATA LOW_PRIORITY INFILE ‘data.txt’ INTO TABLE user;
当然还有IGNORE REPLACE等关键字。
导出数据
如果不指定一个FIELDS子句,缺省值与这样写的相同:
FIELDS TERMINATED BY ‘t’ ENCLOSED BY ” ESCAPED BY ”
如果不指定一个LINES子句,缺省值与这样写的相同:
LINES TERMINATED BY ‘n’
换句话说,缺省值导致读取输入时,LOAD DATA INFILE表现如下:
在换行符处寻找行边界
在定位符处将行分成字段
不要期望字段由任何引号字符封装
将由“”开头的定位符、换行符或“”解释成字段值的部分字面字符
导出数据
相反,缺省值导致在写入输出时,SELECT … INTO OUTFILE表现如下:
在字段之间写定位符
不用任何引号字符封装字段
使用“”转义出现在字段中的定位符、换行符或“”字符
在行尾处写换行符
注意,为了写入FIELDS ESCAPED BY ”,对作为一条单个的反斜线被读取的值,你必须指定2条反斜线值。
##########################################################################################################################

总结一下上家公司的架构演变过程

前言

  虽然公司由于各种原因倒闭解散了,后来起死回生也没有在回去,回头再来看看这个系统是如何一步步演变和进化的。
  该系统具备的功能:
  • 用户模块:用户注册和管理
  • 学校模块:二手商品展示和管理,学校活动的发布和参与
  • 消息模块:学生之间的消息交流和学校的系统通知

 

阶段一、单机构建网站

  入公司的初期,我们只有一台服务器,在这台单机上跑了我们所有的程序和软件。此时我们使用一个容器tomcat,然后使用一些开源的框架如maven+spring+hibernate;最后再选择一个数据库管理系统来存储数据,那就是免费的mysql,然后通过JDBC进行数据库的连接和操作。
  把以上的所有软件都装载同一台机器上,应用跑起来了,也算是一个小系统了。,就是这么的简单粗暴,你没有猜错没有管理后台,要发发布一个活动需要手动去数据库插入数据!!!!!!多么痛的领悟!!
此时系统大致如下:
1

阶段二、应用服务器与数据库分离

  随着APP的上线开始推广,访问量逐步上升,服务器的负载越来越高,在服务器还没有超载的时候,我们就开始做准备,提升网站的负载能力。我们优化了一次代码,但是并没有什么卵用,服务器负载依旧居高不下,主要是数据库读写特别厉害强占了资源后一直使用资源得不到释放,导致tomcat响应也非常慢,APP请求经常超时,要么给服务器加配置,做数据库和服务的分离!!
      吐槽一下阿里云的增加服务器配置,加一倍的配置和新买一台没有太大差距,所以果断的新增加了一台服务器!不仅可以有效地提高系统的负载能力,而且性价比高,为以后进一步分离也做好了准备。此时我们把数据库,web服务器拆分开来,这样不仅提高了单台机器的负载能力,也提高了容灾能力。
应用服务器与数据库分开后的架构如下图所示:
2

阶段三、应用服务器集群

  随着访问量继续增加,单台应用服务器已经无法满足需求了。因为我们在升级过程中,需要停止tomcat来升级war包,人数众多的情况下这肯定是不允许的!以前晚上在使用低谷期,进行升级的方法不在适用了,因为我们发现在凌晨都会有人在使用APP,这使得我们必须改变策略.
       我们需要把应用服务器从一台变成了两台甚至多台,把用户的请求分散到不同的服务器中,从而提高负载能力并且保证服务的不间断运行。多台应用服务器之间没有直接的交互,他们都是依赖数据库各自对外提供服务。著名的做故障切换的软件有keepalived,keepalived是一个类似于layer3、4、7交换机制的软件,他不是某个具体软件故障切换的专属品,而是可以适用于各种软件的一款产品。keepalived配合上ipvsadm又可以做负载均衡,可谓是神器。
系统演变到这里,将会出现下面四个问题
  1. 用户的请求由谁来转发到到具体的应用服务器
  2. 有什么转发的算法
  3. 应用服务器如何返回用户的请求
  4. 用户如果每次访问到的服务器不一样,那么如何维护session的一致性

我们来看看解决问题的方案

  • 1、第一个问题即是负载均衡的问题,一般有5种解决方案:

1、http重定向。HTTP重定向就是应用层的请求转发。用户的请求其实已经到了HTTP重定向负载均衡服务器,服务器根据算法要求用户重定向,用户收到重定向请求后,再次请求真正的集群
优点:简单。   缺点:性能较差。
2、DNS域名解析负载均衡。DNS域名解析负载均衡就是在用户请求DNS服务器,获取域名对应的IP地址时,DNS服务器直接给出负载均衡后的服务器IP。
优点:交给DNS,不用我们去维护负载均衡服务器。
缺点:当一个应用服务器挂了,不能及时通知DNS,而且DNS负载均衡的控制权在域名服务商那里,网站无法做更多的改善和更强大的管理。
3、反向代理服务器。在用户的请求到达反向代理服务器时(已经到达网站机房),由反向代理服务器根据算法转发到具体的服务器。常用的apache,nginx都可以充当反向代理服务器。
优点:部署简单。
缺点:代理服务器可能成为性能的瓶颈,特别是一次上传大文件。
4、IP层负载均衡。在请求到达负载均衡器后,负载均衡器通过修改请求的目的IP地址,从而实现请求的转发,做到负载均衡。
优点:性能更好。
缺点:负载均衡器的宽带成为瓶颈。
5、数据链路层负载均衡。在请求到达负载均衡器后,负载均衡器通过修改请求的mac地址,从而做到负载均衡,与IP负载均衡不一样的是,当请求访问完服务器之后,直接返回客户。而无需再经过负载均衡器。
 

  • 2、第二个问题即是集群调度算法问题,常见的调度算法有10种。

1、rr 轮询调度算法。顾名思义,轮询分发请求。
优点:实现简单
缺点:不考虑每台服务器的处理能力
2、wrr 加权调度算法。我们给每个服务器设置权值weight,负载均衡调度器根据权值调度服务器,服务器被调用的次数跟权值成正比。
优点:考虑了服务器处理能力的不同
3、sh 原地址散列:提取用户IP,根据散列函数得出一个key,再根据静态映射表,查处对应的value,即目标服务器IP。过目标机器超负荷,则返回空。
4、dh 目标地址散列:同上,只是现在提取的是目标地址的IP来做哈希。
优点:以上两种算法的都能实现同一个用户访问同一个服务器。
5、lc 最少连接。优先把请求转发给连接数少的服务器。
优点:使得集群中各个服务器的负载更加均匀。
6、wlc 加权最少连接。在lc的基础上,为每台服务器加上权值。算法为:(活动连接数*256+非活动连接数)÷权重 ,计算出来的值小的服务器优先被选择。
优点:可以根据服务器的能力分配请求。
7、sed 最短期望延迟。其实sed跟wlc类似,区别是不考虑非活动连接数。算法为:(活动连接数+1)*256÷权重,同样计算出来的值小的服务器优先被选择。
8、nq 永不排队。改进的sed算法。我们想一下什么情况下才能“永不排队”,那就是服务器的连接数为0的时候,那么假如有服务器连接数为0,均衡器直接把请求转发给它,无需经过sed的计算。
9、LBLC 基于局部性的最少连接。均衡器根据请求的目的IP地址,找出该IP地址最近被使用的服务器,把请求转发之,若该服务器超载,最采用最少连接数算法。
10、LBLCR 带复制的基于局部性的最少连接。均衡器根据请求的目的IP地址,找出该IP地址最近使用的“服务器”,注意,并不是具体某个服务器,然后采用最少连接数从该组中挑出具体的某台服务器出来,把请求转发之。若该服务器超载,那么根据最少连接数算法,在集群的本服务器组的服务器中,找出一台服务器出来,加入本服务器组,然后把请求转发之。
 

  • 3、第三个问题是集群模式问题,一般3种解决方案:

1、NAT:负载均衡器接收用户的请求,转发给具体服务器,服务器处理完请求返回给均衡器,均衡器再重新返回给用户。
2、DR:负载均衡器接收用户的请求,转发给具体服务器,服务器出来玩请求后直接返回给用户。需要系统支持IP Tunneling协议,难以跨平台。
3、TUN:同上,但无需IP Tunneling协议,跨平台性好,大部分系统都可以支持。
4、第四个问题是session问题,一般有4种解决方案:

  • 4、Session Sticky。session sticky就是把同一个用户在某一个会话中的请求,都分配到固定的某一台服务器中,这样我们就不需要解决跨服务器的session问题了,常见的算法有ip_hash法,即上面提到的两种散列算法。

优点:实现简单。
缺点:应用服务器重启则session消失。
2、Session Replication。session replication就是在集群中复制session,使得每个服务器都保存有全部用户的session数据。
优点:减轻负载均衡服务器的压力,不需要要实现ip_hasp算法来转发请求。
缺点:复制时宽带开销大,访问量大的话session占用内存大且浪费。
3、Session数据集中存储:session数据集中存储就是利用数据库来存储session数据,实现了session和应用服务器的解耦。
优点:相比session replication的方案,集群间对于宽带和内存的压力减少了很多。
缺点:需要维护存储session的数据库。
4、Cookie Base:cookie base就是把session存在cookie中,有浏览器来告诉应用服务器我的session是什么,同样实现了session和应用服务器的解耦。
优点:实现简单,基本免维护。
缺点:cookie长度限制,安全性低,宽带消耗。
 
值得一提的是
nginx目前支持的负载均衡算法有wrr、sh(支持一致性哈希)、fair(本人觉得可以归结为lc)。但nginx作为均衡器的话,还可以一同作为静态资源服务器。
keepalived+ipvsadm比较强大,目前支持的算法有:rr、wrr、lc、wlc、lblc、sh、dh
keepalived支持集群模式有:NAT、DR、TUN
nginx本身并没有提供session同步的解决方案,而apache则提供了session共享的支持。

 
最后我们选了阿里云的负载均衡服务,他保证100%的稳定消除了入口单点的问题,并且提供了加权轮询和最小连接数,以及回话保持的功能,自动剔除有问题的服务器!
 
这让我想起一个段子:
三位女的都去一个公司应聘总裁助理的岗位,面试过程中一个表现平平,一个表现的非常好,一个表现的非常差!最后总裁选了胸最大的一个!这个故事告诉我们一定要模清楚顾客最后的需求,就好像我们选负载均衡做集群一样,我们需要一个非常稳定的转发服务器,并且不能有单点问题,能实现自动剔除有问题的服务器,以及回话保持!这完全符合了我们的所有需求,只是要花点银子!当然是选择在部署最快最高效的方式.用老板的话说就是在创业公司跑最快的最不容死啊(最后被无情打脸)

此时的系统的结构如下
3
 

阶段四、数据库读写分离化

  上面我们总是假设数据库负载正常,但随着访问量的的提高,数据库的负载也在慢慢增大。那么可能有人马上就想到跟应用服务器一样,把数据库一份为二再负载均衡即可。但对于数据库来说,并没有那么简单。假如我们简单的把数据库一分为二,然后对于数据库的请求,分别负载到A机器和B机器,那么显而易见会造成两台数据库数据不统一的问题。那么对于这种情况,我们可以先考虑使用读写分离的方式。
  读写分离后的数据库系统结构如下:
这个结构变化后也会带来两个问题
  1. 主从数据库之间数据同步问题
  2. 应用对于数据源的选择问题
  解决问题方案
  1. 我们可以使用MYSQL自带的master+slave的方式实现主从复制。
  2. 采用第三方数据库中间件,Amoeba。Amoeba是一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy。它集中地响应应用的请求,依据用户事先设置的规则,将SQL请求发送到特定的数据库上执行。基于此可以实现负载均衡、读写分离、高可用性等需求。与MySQL官方的MySQL Proxy相比,作者强调的是amoeba配置的方便(基于XML的配置文件,用SQLJEP语法书写规则,比基于lua脚本的MySQL Proxy简单)。

4

阶段五、用缓存技术缓解读库的压力

1、后台应用层和数据库层的缓存

  随着业务的变更以及用户访问量的增加,逐渐出现了许多用户访问同一部分内容的情况(校园圈),对于这些比较热门的内容,没必要每次都从数据库读取。我们可以使用缓存技术,例如可以使用google的开源缓存技术guava或者使用memcacahe作为应用层的缓存,也可以使用redis作为数据库层的缓存。
2、登陆认证信息token的缓存
  除了数据缓存,还有用户登陆的后认证的token信息。
  优点
  • 减轻数据库的压力
  • 大幅度提高访问速度
  缺点
  • 需要维护缓存服务器
  • 提高了编码的复杂性

值得一提的是
缓存集群的调度算法不同与上面提到的应用服务器和数据库。最好采用“一致性哈希算法”,这样才能提高命中率。这个就不展开讲了,有兴趣的可以查阅相关资料。
 

  加入缓存后的结构
5

 未完待续,后面继续补充