问题说明
MySQL 如何设置不区分表名大小写。
处理办法
一般情况下 Linux 服务器默认安装 MySQL 的数据库表名是区分大小写的,如果 ECS 上安装的 MySQL 不支持表名区分大小下,则按照如下方法操作即可:
-
用 root 登录,修改 /etc/my.cnf (注意:以实际 my.cnf 配置文件路径为准)
-
在 [mysqld] 节点下,加入一行: lower_case_table_names=1
-
重启 MySQL 即可;
问题说明
MySQL 如何设置不区分表名大小写。
处理办法
一般情况下 Linux 服务器默认安装 MySQL 的数据库表名是区分大小写的,如果 ECS 上安装的 MySQL 不支持表名区分大小下,则按照如下方法操作即可:
用 root 登录,修改 /etc/my.cnf (注意:以实际 my.cnf 配置文件路径为准)
在 [mysqld] 节点下,加入一行: lower_case_table_names=1
重启 MySQL 即可;
shell命令操作语法和JavaScript很类似,其实控制台底层的查询语句都是用javascript脚本完成操作的。使用shell 命令,需要启动mongo.exe。
常用shell命令如下:
1、查询本地所有数据库名称
> show dbs;
2、切换至指定数据库环境(若无指定的数据库,则创建新的库)
> use mydb;
3、查询当前库下的所有聚集集合collection(相当于table)
> show collections;
4、创建聚集集合
> db.createCollection('mycollection');
5、查询聚集集合中数据条数
> db.mycollection.count();
6、插入数据
> db.mycollection.insert({'username':'xyz_lmn','age':26,'salary':120});
往’mycollection’聚集集合中插上一条数库,name为’xyz_lmn’,age为’26’,salary为’120′
7、查询age等于26的数据
> db.mycollection.find({"age":26});
8、查询salary大于100的数据
> db.mycollection.find({salary:{$gt:100}});
9、查询age小于30,salary大于100的数据
> db.mycollection.find({age:{$lt:30}},{salary:{$gt:100}});
10、查询salary小于40或salary大于200的数据
> db.mycollection.find({$or: [{salary: {$lt:40}}, {salary: {$gt:200}}]});
11、查询指定列的数据
> db.mycollection.find({},{age:1,salary:1});
1表示显示此列的意思,也可以用true表示
12、查询username中包含’e’的数据
> db.mycollection.find({username:/e/});
13、查询以a打头的数据
> db.mycollection.find({username:/^a/});
14、查询age列数据,并去掉重复数据
> db.mycollection.distinct('age');
15、查询前10条数据
> db.mycollection.find().limit(10);
16、查询1条以后的所有数据
> db.mycollection.find().skip(1);
17、查询第一条数据
> db.mycollection.findOne();
18、查询结果集的记录数(查询salary小于40或大于100的记录数)
db.mycollection.find({$or: [{salary: {$lt:40}}, {salary: {$gt:100}}]}).count();
19、按salary升序排序
> db.mycollection.find().sort({salary:1});
按照salary字段升序排序
20、降序
> db.mycollection.find().sort({salary:-1});
按照salary字段降序排序
21、根据username修改age
> db.employee.update({username:'jim'},{$set:{age:22}},false,true);
db.collection.update( criteria, objNew, upsert, multi )
objNew : update的对象和一些更新的操作符(如$,$inc…)等,也可以理解为sql update查询内set后面的
upsert : 如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : MongoDB默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
22、将指定username的age字段增加5
> db.mycollection.update({username:'jim'},{$inc:{age:5}},false,true);
将username为‘jim’的age字段加5
23、删除username为’rose’的数据
> db.mycollection.remove({uname:'rose'});
24、集合collection重命名
> db.mycollection.renameCollection('c_temp');
将mycollection集合重命名为’c_temp’
25、删除集合
> db.c_temp.drop();
删除名为’c_temp’的集合
26、删除当前数据库
> db.dropDatabase();

db.createUser({
user: 'testname', // 用户名
pwd: 'testpwd', // 密码
roles: [
{
role: 'readWrite', // 读写权限
db: 'test' // 所属数据库
}
]
})
mongod --dbpath mongoData --auth
show dbs // 报错,因为没有验证
use test // 切换到test数据库
db.auth('testname', 'testpwd') // 1
show collections // 可以查看表
use local // 切换到local数据
show collections // 报错
db.auth('testname', 'testpwd') // 报错,因为testname是test数据的用户
mongodb可以同时存在多个数据库。
mongodb的用户是属于某个数据库的。即,你创建的某个用户只能在一数据库中使用。
mongodb启动有两种模式,需要验证和不需要验证。默认不需要验证,当你使用验证模式启动后,对数据的所有操作必须通过验证并且具有相应权限才可以操作。
use test // 切换到test数据库
db.auth('testname', 'testpwd') // 验证
db.changeUserPassword('testname', 'newtestpwd') // 修改密码
mongodb副本集即客户端连接到整个副本集,不关心具体哪一台机器是否挂掉。主服务器负责整个副本集的读写,副本集定期同步数据备份,一旦主节点挂掉,副本节点就会选举一个新的主服务器,这一切对于应用服务器不需要关心。副本集中的副本节点在主节点挂掉后通过心跳机制检测到后,就会在集群内发起主节点的选举机制,自动选举一位新的主服务器。选举还有个前提条件,参与选举的节点数量必须大于副本集总节点数量的一半,如果已经小于一半了所有节点保持只读状态。因此,官方推荐我们的副本集机器数量至少为3个:一个主节点,两个副本节点。当然,mongodb副本集中可以有很多类型的节点,其中有一个仲裁节点,即当参与选举的节点无法选出主节点时仲裁节点充当仲裁的作用。仲裁节点不存储数据,只是仲裁。所以,我们的副本集可以设置为:1主+1从+1仲裁。
那么我们准备3台服务器:192.168.198.224(主),192.168.198.225(从),192.168.198.226(仲裁)。
curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-amazon-3.4.6.tgz
tar -zxvf mongodb-linux-x86_64-amazon-3.4.6.tgz
mv mongodb-linux-x86_64-amazon-3.4.6/ /usr/local/mongodb
cd /usr/local/mongodb
mkdir -p data/db
mkdir log
touch log/mongod.log
mkdir etc
touch etc/mongod.conf
vim etc/mongod.conf
为了启动方便,我们可以将mongodb的启动配置项直接在配置文件中:
dbpath = /usr/local/mongodb/data/db # 指定数据库路径
logpath = /usr/local/mongodb/log/mongod.log # 指定mongodb日志文件
logappend = true # 使用追加的方式写日志
port = 27017 #设置端口号为27017
fork = true #设置以守护进程的方式启动mongod
replSet = myrs #设置副本集的名字为myrs,同一副本集群的replSet名称必需相同
cd /usr/local/mongodb
./bin/mongod -f ./etc/mongod.conf #指定以mongod.conf配置启动mongod
登录任意一台机器的mongodb后台管理shell:
cd /usr/local/mongodb
./bin/mongo
use admin
config = {
"_id":"rs0",
"members":[
{"_id":0,"host":"192.168.198.223:27017"},
{"_id":1,"host":"192.168.198.225:27017"},
{"_id":2,"host":"192.168.198.226:27017",arbiterOnly:true}
]
}
rs.initiate(config); #初始化配置
注意:如果执行rs.initiate(config)报错,那么我们需要检查三台服务器的防火墙27017端口是否开放。 如果没有问题,我们可以查看集群节点:
rs.status();
至此,整个副本集已经搭建成功了。
那么,我们可以测试一下副本集的基本功能:
此时在我的机器上192.168.198.224是主节点,我们用mongo来登录shell。
cd /usr/local/mongodb
./bin/mongo
use test #创建test数据库
db.testdb.insert({"name":"yaya"}); #插入数据
我们用副本节点登录shell,我这里是192.168.198.225:
cd /usr/local/mongodb
./bin/mongo
use test
show tables
此时会报错:
[thread1] Error: listCollections failed: {
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk"
}
因为mongodb默认是从主节点读写数据的,副本节点上不允许读,需要设置副本节点可以读。
myrs:SECONDARY> db.getMongo().setSlaveOk();
此时就可以读取数据了:
repset:SECONDARY> db.testdb.find();
控制台输出:{ “_id” : ObjectId(“59676d711881041abab44477”), “name” : “yaya” }
所以,数据复制的功能是可用的。
将主节点192.168.198.224的mongod进程杀死:
myrs:PRIMARY> use admin
myrs:PRIMARY> db.shutdownServer()
此时可以看到,192.168.198.225原本是副节点,此时自动转换为主节点。可以通过rs.status()来查看。
本文将详细介绍MongoDB数据库关于文档的增删改查
要将数据插入到 MongoDB 集合中,需要使用 MongoDB 的 insert()或save()方法,还有insertOne()或insertMany()方法
【insert()】
insert()命令的基本语法如下
db.COLLECTION_NAME.insert(document)
在插入的文档中,如果不指定_id参数,那么 MongoDB 会为此文档分配一个唯一的ObjectId。_id为集合中的每个文档唯一的12个字节的十六进制数
如果数据库中不存在集合,则MongoDB将创建此集合,然后将文档插入到该集合中
![]()
要在单个查询中插入多个文档,可以在insert()命令中传递文档数组
![]()
可以使用js语法,插入多个文档
![]()
【save()】
插入文档也可以使用db.post.save(document)。 如果不在文档中指定_id,那么save()方法将与insert()方法一样自动分配ID的值。如果指定_id,则将以save()方法的形式替换包含_id的文档的全部数据。
也就是说save()方法和insert()方法的区别是,save()方法可以复写或修改,而insert()方法不可以
db.post.save(document)


【insertOne()】
使用db.collection.insertOne()方法可以将单个文档插入到集合中

【insertMany()】
使用db.collection.insertMany()方法可以将多个文档插入到集合中

【find()】
要从MongoDB集合查询数据,需要使用MongoDB的find()方法,默认返回结果中的前20条文档,输入”it”显示接下来的20条文档。
find()命令的基本语法如下:
db.COLLECTION_NAME.find(document)
find()方法将以非结构化的方式显示所有文档

可以限定查询条件

可以通过find 的第二个参数来指定返回的键,值为1或true表示显示该键,值为0或false表示不显示该键

find()方法下的count()方法可以显示符合条件的文档数量
![]()
【findOne()】
findOne()方法只返回一个文档,该文档是最早被添加的文档
![]()
【比较操作符】
小于 {<key>:{$lt:<value>}}
小于或等于 {<key>:{$lte:<value>}}
大于 {<key>:{$gt:<value>}}
大于或等于 {<key>:{$gte:<value>}}
不等于 {<key>:{$ne:<value>}}
等于 {<key>:{$eq:<value>}}
取得x小于2的值

取得x大于等于2的值

取得x不等于2的值

【逻辑操作符】
可以使用逻辑操作符and、and、or来表示与、或
{ $and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ] }
{ $nor: [ { <expression1> }, { <expression2> }, ... { <expressionN> } ] }

【正则表达式】
文档查询可以使用正则表达式,但只支持字符串类型的数据

【$where】
$where操作符功能强大而且灵活,它可以使用任意的JavaScript作为查询的一部分,包含JavaScript表达式的字符串或者JavaScript函数

使用字符串

使用函数

限制与跳过
【limit()】
如果需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数
默认返回结果中的前20条文档,输入”it”显示接下来的20条文档
如果没有指定limit()方法中的参数则显示集合中的所有数据
db.COLLECTION_NAME.find().limit(NUMBER)

【skip()】
可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数
db.COLLECTION_NAME.find().skip(NUMBER)

排序
【sort()】
在MongoDB中使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列
db.COLLECTION_NAME.find().sort({KEY:1})

更新文档
MongoDB 使用update()或save()方法来更新集合中的文档
【update()】
update() 方法用于更新已存在的文档。语法格式如下:
db.collection.update(<query>,<update>,{upsert:<boolean>, multi: <boolean>,writeConcern:<document>})
query : update的查询条件,类似sql update查询内where后面的
update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新
writeConcern :可选,抛出异常的级别
[注意]经过测试,upsert参数无法设置为true或者false,都可以插入新的字段

mongodb默认只更新找到的第一条记录,将x:1,更新为x:10

要特别注意的是,如果不使用$set,则将文档的内容替换为x:10

更新全部记录,将x:10,更新为x:1

mongodb默认只添加到更新找到的第一条记录,将x:1的记录,添加z:1

将找到的x:2的全部记录,添加z:2

【save()】
save()方法可以插入或更新文档,如果参数中的文档的_id与集合中所存在的_id都不同,则插入;如果相同,则更新

删除文档
MongoDB remove()函数是用来移除集合中的数据
【remove()】
默认地,mongodb删除符合条件的所有文档
db.collection.remove(<query>,{justOne: <boolean>, writeConcern: <document>})
query :删除的文档的条件。
justOne : (可选)如果设为 true 或 1,则只删除一个文档。
writeConcern :(可选)抛出异常的级别。
只删除符合条件的第一个文档

删除符合条件的所有文档

客户端下载:
https://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/cn/ocs/0.1.9/assets/libmemcached-1.0.16.gz?spm=5176.doc48432.2.1.eQ5tPY&file=libmemcached-1.0.16.gz
客户端介绍:
http://pecl.php.net/support.php?spm=5176.doc48432.2.2.eQ5tPY
客户端版本介绍:
http://pecl.php.net/package/memcached?spm=5176.doc48432.2.3.GstFhV
注意:您已经有 php memcache 等环境,请注意教程中的一些提示,以免生产环境被覆盖,导致业务不可用,在升级及再编译环境前请做好环境备份。
windows 系列版本
如果采用标准的 php memcached 扩展不能成功搭建,可以考虑换成手工拼包的形式来访问云数据库 Memcache,连接方式请参考如下链接,示例代码非常简单,与 php memcached 的区别就是仅支持主流接口,需自己补充某些特定接口,安装及使用方法请参见这里。
Centos 及 Aliyun Linux 6系列版本
注意:Memcached 2.2.0 扩展必须使用 libmemcached 1.0.x 的库,低于1.0的库不再能够成功编译。编译 libmemcached 时 GCC 要求在4.2及以上。
执行 rpm –qa | grep php 查看系统中是否有 PHP 环境,如果没有则执行 yum install php-devel,php-common,php-cli 安装包含源码编译的 PHP。
建议使用 php 5.3及以上版本。php 5.2部分版本系列源代码会有 zend_parse_parameters_none 函数会出错,如需使用请参照 php 官方相关文档。如是源代码编译,请按照官方 php 编译升级的办法进行。
检测是否有已安装了 SASL 相关环境包,如没有,则执行 yum install cyrus-sasl-plain cyrus-sasl cyrus-sasl-devel cyrus-sasl-lib 安装 SASL 相关环境。
检测下是否有已安装了 libmemcached 源码包,若没有,则执行以下命令安装 libmemcached 源码包(推荐版本 libmemcached-1.0.18)。
wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
tar zxvf libmemcached-1.0.18.tar.gz
cd libmemcached-1.0.18
./configure --prefix=/usr/local/libmemcached --enable-sasl
make
make install
cd ..
注意:
请先检测下是否已安装了 memcached 客户端包(包含源码包)。如有则不需要安装,但需要重新编译增加 -enable-memcached-sasl 这个扩展。
wget http://pecl.php.net/get/memcached-2.2.0.tgz
tar zxvf memcached-2.2.0.tgz
cd memcached-2.2.0
phpize(如果系统中有两套PHP环境,需绝对路径调用该命令/usr/bin/phpize,该路径为使用云数据库Memcache的PHP环境路径)
./configure --with-libmemcached-dir=/usr/local/libmemcached --enable-memcached-sasl(注意这个参数)
make
make install
extension=memcached.so memcached.use_sasl = 1。
Centos及 Aliyun Linux 5系列版本 【64位版本】
执行rpm –qa | grep php 查看系统中是否有 php 环境,如果没有则执行 yum install php53 php53-devel 安装包含源码编译的 php;如有 php 则不要安装。建议使用 php 5.3(含)以上版。
php 5.2部分版本系列源代码会有 zend_parse_parameters_none 函数会出错,如需使用请参照 php 官方相关文档。
检测下是否已安装了 libmemcached(包含源码包),如有则不需要安装,如没有则执行以下命令安装(推荐版本 libmemcached 1.0.2)。
wget http://launchpad.net/libmemcached/1.0/1.0.2/+download/libmemcached-1.0.2.tar.gz
tar -zxvf libmemcached-1.0.2.tar.gz
cd libmemcached-1.0.2
./configure --prefix=/usr/local/libmemcached --enable-sasl
make
make install
cd ..
注意:
请先检测下是否有已安装了 memcached 客户端包(包含源码包)。如有则不需要安装,但需要重新编译增加 -enable-memcached-sasl 这个扩展。
wget http://pecl.php.net/get/memcached-2.0.0.tgz tar -zxvf memcached-2.0.0.tgz
cd memcached-2.0.0 phpize(如果系统中有两套PHP环境,需绝对路径调用该命令/usr/bin/phpize,该路径为使用云数据库Memcache的PHP环境路径,请在memcached源码目录内执行phpize)
./configure --with-libmemcached-dir=/usr/local/libmemcached --enable-memcached-sasl(注意这个参数)
make
make install
修改 php.ini 文件(locate 找该文件,yum 安装的一般在 /etc/php.ini。 如果系统中有两套 PHP 环境,需找到使用云数据库 Memcache 的 PHP 环境路径,对应修改之),增加 extension=memcached.so memcached.use_sasl = 1 。
执行 php –m |grep ,memcached ,若显结果有 memcache 表示环境已支持 memcache。
使用该页面最后的测试代码测试下是否环境部署成功,请修改代码中相应的地址、端口、用户名及密码。
Ubuntu Debian 等系列版本
方案一:执行 vim /etc/apt/source.list,在最前面添加以下内容。
deb http://mirrors.aliyun.com/ubuntu/ precise main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ precise-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ precise-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ precise-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ precise-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ precise main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ precise-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ precise-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ precise-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ precise-backports main restricted universe multiverse
apt-get update //更新一下列表
方案二: 通过 wget http://oss.aliyuncs.com/aliyunecs/update_source.zip 下载 update_source 的压缩包,解压后予执行权限 chmod 777 文件名 ,然后执行该脚本进行自动变更源操作。
首先需要使用 dpkg –s 安装包名,例如 dpkg –s gcc,确认是否安装了 gcc-c++ 等组件。如没有请执行 apt-get build-dep gcc apt-get install build-essential。
首先需要使用 dpkg –s 安装包名,例如 dpkg –s php,确认是否安装了 php 等组件。如没有请执行 apt-get install php5 php5-dev (同时会自动安装php5-cli和php5-common)。
首先需要使用 dpkg –s 安装包名, 例如 dpkg –s libsasl2,确认是否安装了 libsasl2 cloog-ppl 等组件,如没有请执行以下命令。
apt-get install libsasl2-dev cloog-ppl
cd /usr/local/src
注意:请先检测下是否有已安装了这些包(包含源码包),如有则不需要安装。
wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
tar -zxvf libmemcached-1.0.18.tar.gz
cd libmemcached-1.0.18
./configure --prefix=/usr/local/libmemcached
make
make install
cd ..
注意:请先检测下是否有已安装了 memcached 客户端包(包含源码包),如有则不需要安装,但需要重新编译增加 -enable-memcached-sasl 这个扩展。
wget
http://pecl.php.net/get/memcached-2.2.0.tgz tar zxvf memcached-2.2.0.tgz
cd memcached-2.2.0 phpize5
./configure --with-libmemcached-dir=/usr/local/libmemcached --enable-memcached-sasl
make
make install
echo "extension=memcached.so" >>/etc/php5/conf.d/pdo.ini echo "memcached.use_sasl = 1" >>/etc/php5/conf.d/pdo.ini
php -m |grep mem memcached
如果显示出该组件代表安装完成,配置完毕。
示例1:基本的连接云数据库 Memcache 及 set/get 操作
<?php
$connect = new Memcached; //声明一个新的memcached链接
$connect->setOption(Memcached::OPT_COMPRESSION, false); //关闭压缩功能
$connect->setOption(Memcached::OPT_BINARY_PROTOCOL, true); //使用binary二进制协议
$connect->setOption(Memcached::OPT_TCP_NODELAY, true); //重要,php memcached有个bug,当get的值不存在,有固定40ms延迟,开启这个参数,可以避免这个bug
$connect->addServer('aaaaaaaaaa.m.yyyyyyyyyyy.ocs.aliyuncs.com', 11211); //添加OCS实例地址及端口号
$connect->setSaslAuthData('aaaaaaaaaa', 'password'); //设置OCS帐号密码进行鉴权,如已开启免密码功能,则无需此步骤;新版OCS的username可以置空
$connect->set("hello", "world");
echo 'hello: ',$connect->get("hello");
$connect->quit();
?>
示例2:在云数据库 Memcache 中缓存一个数组
<?php
$connect= new Memcached; //声明一个新的memcached链接
$connect->setOption(Memcached::OPT_COMPRESSION, false); //关闭压缩功能
$connect->setOption(Memcached::OPT_BINARY_PROTOCOL, true);//使用binary二进制协议
$connect->setOption(Memcached::OPT_TCP_NODELAY, true); //重要,php memcached有个bug,当get的值不存在,有固定40ms延迟,开启这个参数,可以避免这个bug
$connect->addServer('xxxxxxxx.m.yyyyyyyy.ocs.aliyuncs.com', 11211);//添加OCS实例地址及端口号
$connect->setSaslAuthData('xxxxxxxx', 'bbbbbbbb');//设置OCS帐号密码进行鉴权,如已开启免密码功能,则无需此步骤
$user = array(
"name" => "ocs",
"age" => 1,
"sex" => "male"
); //声明一组数组
$expire = 60; //设置过期时间
test($connect->set('your_name',$user,$expire), true, 'Set cache failed');
if($connect->get('your_name')){
$result =$connect->get('your_name');
}else{
echo "Return code:", $connect->getResultCode();
echo "Retucn Message:", $connect->getResultMessage (); //如出现错误,解析出返回码
$result=" ";
}
print_r($result);
$connect->quit();
function test($val, $expect, $msg)
{
if($val!= $expect) throw new Exception($msg);
}
?>
示例3:云数据库 Memcache 与 MySQL 数据库结合使用
<?php
$connect = new Memcached; //声明一个新的memcached链接
$connect->setOption(Memcached::OPT_COMPRESSION, false);//关闭压缩功能
$connect->setOption(Memcached::OPT_BINARY_PROTOCOL, true);//使用binary二进制协议
$connect->setOption(Memcached::OPT_TCP_NODELAY, true); //重要,php memcached有个bug,当get的值不存在,有固定40ms延迟,开启这个参数,可以避免这个bug
$connect->addServer('xxxxxx.m.yyyyyyyy.ocs.aliyuncs.com', 11211);//添加实例地址 端口号
$connect->setSaslAuthData('xxxxxx', 'my_passwd');//设置OCS帐号密码进行鉴权,如已开启免密码功能,则无需此步骤
$user = array(
"name" => "ocs",
"age" => 1,
"sex" => "male"
); //定义一组数组
if($connect->get('your_name'))
{
$result =$connect->get('your_name');
print_r($result);
echo "Found in OCS, get data from OCS"; //如果获取到数据,则打印此数据来源于OCS
exit;
}
else
{
echo "Return code:", $connect->getResultCode();
echo "Retucn Message:", $connect->getResultMessage ();//抛出code返回码
$db_host='zzzzzz.mysql.rds.aliyuncs.com'; //数据库地址
$db_name='my_db'; //database name
$db_username='db_user'; //数据库用户名
$db_password='db_passwd';//数据库用户密码
$connection=mysql_connect($db_host,$db_username,$db_password);
if (!mysql_select_db($db_name, $connection))
{
echo 'Could not select database'; //数据库连接不成功则抛出错误信息
exit;
}
$sql = "SELECT name,age,sex FROM test1 WHERE name = 'ocs'";
$result = mysql_query($sql, $connection);
while ($row = mysql_fetch_assoc($result))
{
$user = array(
"name" => $row["name"],
"age" => $row["age"],
"sex" => $row["sex"],
);
$expire = 5; //设置数据在缓存中的过期时间
test($connect->set('your_name',$user,$expire), true, 'Set cache failed'); //写入OCS缓存
}
mysql_free_result($result);
mysql_close($connection);
}
print_r($connect->get('your_name')); //打印出 获取到的数据
echo "Not Found in OCS,get data from MySQL"; //确认从数据库获取的数据
$connect->quit();
function test($val, $expect, $msg)
{
if($val!= $expect) throw new Exception($msg);
}
?>
Memcached尽管是“分布式”的缓存系统,但服务器端并没有分布式功能。各个 Memcached不会互相通信以共享信息。分布式完全取决于客户端实现。
Memcached的分布式客户端
客户端可以通过配置SockIOPool的servers参数保存服务器地址列表,通过
weight参数配置每台服务器的权重。SockIOPool提供了连接池的服务,可以通过 SockIOPool来配置memcahce服务器相关信息,如最大连接数,最小连接数等。
一个key只能存放在一台Memcache服务器上,是不会在多个服务器上有多份拷贝的,这样的话既可以防止出现刷新不同步的情况,也可以避免磁盘空间的浪费
1: 服务器端不关心分布式。
2: 依靠客户端来实现分布式 。
3: 客户端存储着可以访问到的Memcached服务器列表 。
4: 在客户端用算法来保证,对同样key值的数据,读写都操作同一个服务器。
提高命中率。
f参数:
factor增长因子,默认为1.25,曾经为2,值越小,slab中chunk size差距 越小,内存浪费越小。1.25适合缓存几百字节的对象。
建议:计算一下数据的预期平均长度,调整factor,以获得最恰当的设置。
n参数:chunk初始值
slab尾部剩余空间
解决办法:规划slab=chunk*n整数倍
slab中chunk利用率低:申请的slab只存放了一个Item
解决办法:规划slab=chunk
chunk存储Item浪费
如Item是100,存到128字节chunk,就有28字节浪费
解决办法:规划chunk=Item
在Memcached中可以保存的item数据量是没有限制的,只要内存足够。
Memcached单进程最大使用内存为2G,要使用更多内存,可以分多个端口开启多
个Memcached进程。
Memcached设置Item为最大30天的过期时间,设置为永久的也会在这个时间过期,
常量REALTIME_MAXDELTA为606024*30控制。
Memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问
题,当内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删
除不使用的缓存。
最大键长为250字节,大于该长度无法存储,单个item最大数据是1MB,超过1MB数据不予存储。
通过缓存数据库查询结果,减少数据库访问次
数;还有就是缓存热点数据,以提高Web应用的速度、提高可扩展性。
缓存简单的基于行的查询结果。
缓存的不只是SQL数据,可以缓存常用的热点数据,比如页面,以节省CPU时间使用分层的缓存。
特别注意:当数据更新时需要更新缓存。
分布式应用。
数据库前段缓存。
服务器间数据共享。
变化频繁,查询频繁的数据,但是不一定写入数据库,比如:用户在线状态 。
变化不频繁,查询频繁,不管是否入库,都比较适合使用。
1: 变化频繁, 一变化就要入库类的应用,比如股票,金融。
2: 那些不需要“分布”的,不需要共享的,或者干脆规模小到只有一台服务器的应用,
memcached不会带来任何好处,相反还会拖慢系统效率,因为网络连接同样需要资源。
3: 缓存对象的大小大于1MB。
4: key的长度大于250字符。
Memcached 安装使用存储
http://www.jianshu.com/p/2b3c43c1778c
java 使用memcached以及spring 配置memcached
http://www.jianshu.com/p/6f264bf5d9f9
memcached优化
http://www.jianshu.com/p/789d208036f5
Centos7 搭建mariaDB + nginx + php环境
[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum makecache
[root@localhost ~]# yum update
[root@localhost ~]# yum install xorg-x11-xauth
# 编辑/etc/ssh/sshd_config文件中的X11Forwarding参数为yes
[root@localhost ~]# vim /etc/ssh/sshd_config
[root@localhost ~]# yum -y install gcc gcc-c++ make unixODBC wxBase wxGTK wxGTK-gl ncurses-devel zlib zlib-devel openssl openssl-devel kernel-devel m4 xmlto net-tools lksctp-tools socat cmake perl perl-JSON libtool pcre pcre-devel yasm yasm-devel libmcrypt libmcrypt-devel libvpx libvpx-devel tiff tiff-devel libpng libpng-devel freetype freetype-devel jpeg jpeg-devel libgd libgd-devel t1lib t1lib-devel gd gd-devel
[root@localhost ~]# vim /etc/hostname
[root@localhost ~]# vim /etc/sysconfig/network
[root@localhost ~]# vim /etc/hosts
[root@localhost ~]# hostname localhost
添加新的用户账号使用useradd命令,其语法如下
useradd 选项 用户名
其中各选项含义如下:
代码:
用户名 指定新账号的登录名
1.添加nginx用户
[root@localhost ~]# groupadd nginx
[root@localhost ~]# useradd -c nginx -g nginx nginx -s /sbin/nologin
[root@localhost ~]# groupadd www
[root@localhost ~]# useradd -c www -g www www -s /sbin/nologin
[root@localhost]# yum -y install mariadb mariadb-server
[root@localhost ~]# systemctl enable mariadb
[root@localhost ~]# systemctl start mariadb
[root@localhost ~]# mysql_secure_installation
# 首先是设置密码,会提示先输入密码,初次运行直接回车
Enter current password for root (enter for none):
# 设置密码,是否设置root用户密码,输入y并回车或直接回车
Set root password? [Y/n]
# 设置root用户的密码
New password:
# 再输入一次你设置的密码
Re-enter new password:
# 其他配置
# 是否删除匿名用户,回车
Remove anonymous users? [Y/n]
# 是否禁止root远程登录,回车
Disallow root login remotely? [Y/n]
# 是否删除test数据库,回车
Remove test database and access to it? [Y/n]
# 是否重新加载权限表,回车
Reload privilege tables now? [Y/n]
# 初始化MariaDB完成,接下来测试登录
# mysql -uroot -proot密码
# 允许的IP地址,%为任意地址
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'IP地址' IDENTIFIED BY 'youpassword' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
[root@localhost ~]# yum -y install php php-devel
[root@localhost ~]# yum -y install php-mysql php-gd php-imap php-ldap php-odbc php-pear php-xml php-xmlrpc
# 安装 php-fpm
[root@localhost ~]# yum -y install php-fpm
# 设置fpm开机自启动
[root@localhost ~]# systemctl enable php-fpm
# 启动fpm
[root@localhost ~]# systemctl start php-fpm
# php-fpm配置文件路径/etc/php-fpm.conf
# 切换到src目录
[root@localhost ~]# cd /usr/local/src
# 下载nginx源码包
[root@localhost src]# wget http://nginx.org/download/nginx-1.12.0.tar.gz
# 解压并切换到nginx目录
[root@localhost src]# tar zxvf nginx-1.12.0.tar.gz
[root@localhost src]# cd nginx-1.12.0
# 配置编译选项
[root@localhost nginx-1.12.0]# ./configure --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-pcre
# 安装
[root@localhost nginx-1.12.0]# make & make install
# 常规启动、关闭和重启,不会改变启动时指定的配置文件
[root@localhost ~]# /usr/local/nginx/sbin/nginx
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s stop
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
# 设置开机自启动
[root@localhost ~]# vim /lib/systemd/system/nginx.service
# 写入以下内容
# --------------------------------------------------
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target
# --------------------------------------------------
[root@localhost ~]# systemctl enable nginx
# 修改nginx.conf,去掉以下代码的注释
location ~ .php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}
# 重启nginx
[root@localhost]# /usr/local/nginx/sbin/nginx -s reload
# 修改nginx配置文件
# 源文件
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# 修改后的文件,将 /scripts 修改为$document_root
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
公司数据库没有版本控制,这个就相当坑爹了,问以前的技术,就是在本地建一个表,然后导入到线上,WTF。目前就只能临时开启远程连接数据了,后面在使用版本控制
centos7 之前的防火墙是不一样的,比如你要添加3306端口:
## 全部
iptables -A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT
## 部分ipiptables
iptables -A INPUT -p tcp -s 138.111.21.11 -dport 3306 -j ACCEP
service iptables save
service iptables restart
## 查看 iptables
iptables -L -n
但这个在centos7 就不好使,查看文档才知道centos7 使用了增强版firewall
firewall-cmd --zone=public --permanent --add-port=3306/tcp
1、firwall-cmd:是Linux提供的操作firewall的一个工具;
2、--permanent:表示设置为持久;
3、--add-port:标识添加的端口;
4、--zone=public:指定的zone为public;
当然如果不太习惯使用命令,我们可以直接改配置文件

进入etc/firewalld/zone中,修改public.xml
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>Public</short>
<description>For use in public areas.</description>
<rule family="ipv4">
<source address="122.10.70.234"/>
<port protocol="udp" port="514"/>
<accept/>
</rule>
<rule family="ipv4">
<source address="123.60.255.14"/>
<port protocol="tcp" port="10050-10051"/>
<accept/>
</rule>
<rule family="ipv4">
<source address="192.249.87.114"/> 放通指定ip,指定端口、协议
<port protocol="tcp" port="80"/>
<accept/>
</rule>
<rule family="ipv4"> 放通任意ip访问服务器的9527端口
<port protocol="tcp" port="9527"/>
<accept/>
</rule>
</zone>
上述配置文件可以看出:
1、添加需要的规则,开放通源ip为122.10.70.234,端口514,协议tcp;
2、开放通源ip为123.60.255.14,端口10050-10051,协议tcp;/3、开放通源ip为任意,端口9527,协议
# 重启
service firewalld restart
# 开启
service firewalld start
# 关闭
service firewalld stop
# 查看firewall 服务状态
systemctl status firewall
# 查看防火墙
firewall-cmd --list-all

开启服务器3306对外开放后,还需要设置数据库用户授权
在数据库mysql 中的user表中可以看到默认是只能本地连接的,所有可以添加一个用户
# 针对ip
create user 'root'@'192.168.10.10' identified by 'password';
#全部
create user 'root'@'%' identified by 'password';
建议还是针对于ip开放吧,不要全部开放
授权用户:
# 给用户最大权限
grant all privileges on *.* to 'root'@'%' identified by 'password';
# 给部分权限(test 数据库)
grant all privileges on test.* to 'root'@'%' identified by 'password' with grant option;
# 刷新权限表
flush privileges;
# show grants for 'root'@'localhost';

接下来就是可以本地连接了
参考文章:
http://blog.sina.com.cn/s/blog_4c197d4201017rgl.html
用户授权:
http://www.cnblogs.com/xujishou/p/6306765.html
MariaDB Galera Cluster是MariaDB的同步多主集群。它仅在Linux上可用,并且仅支持xtraDB/InnoDB存储引擎,对MyISAM也有一定的支持(https://mariadb.com/kb/en/mariadb/galera-cluster-system-variables/#wsrep_replicate_myisam),
特征:
优点:
它依赖于wsrep API(https://launchpad.net/wsrep):
wsrep API定义了一组应用程序回调和复制库调用,以实现事务数据库和类似应用程序的同步写入复制。在从应用程序详细信息中抽象和分离复制实现。虽然此接口的主要目标是基于认证的多主机复制,但同样适用于异步和同步主/从复制。
它的复制过程也是基于认证的,基于WSREP API,大量的配置参考:
https://mariadb.com/kb/en/mariadb/galera-cluster-system-variables/#wsrep_replicate_myisam
Galera可以利用四个端口:
三台机器:10.0.1.49,10.10.240.113,10.0.1.61
其实用起来可以是这样的:

前面使用LVS等进行调度,当然在中间可以使用中间件进行读写分离
https://downloads.mariadb.org/mariadb/repositories/
centos7 yum如下:
[root@LinuxEA ~]# cat > /etc/yum.repos.d/mariadb.repo << EOF
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.0/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
EOF
[root@LinuxEA ~]# yum install socat MariaDB-Galera-server MariaDB-client rsync galera
其他版本tar包安装下载地址:
https://downloads.mariadb.org/mariadb-galera/+releases/
本次使用二进制安装:
mariadb-galera安装:http://download.nus.edu.sg/mirror/mariadb//mariadb-galera-10.0.30/bintar-linux-x86_64/mariadb-galera-10.0.30-linux-x86_64.tar.gz
galera安装:http://releases.galeracluster.com/centos/7/x86_64/galera-3-25.3.20-2.el7.x86_64.rpm
防火墙添加:
iptables -I INPUT 4 -p tcp -m tcp -m state --state NEW -m multiport --dports 3306,4444,4567,4568 -m comment --comment "mariadb-galera" -j ACCEPT
其他依赖包:
yum install socat MariaDB-client rsync galera lsof
文档参考
解压
[root@LinuxEA /data]# tar xf mariadb-galera-10.0.30-linux-x86_64.tar.gz -C /usr/local/
[root@LinuxEA /data]# cd /usr/local/
[root@LinuxEA /usr/local]# ln -s mariadb-galera-10.0.30-linux-x86_64/ mysql
安装
[root@LinuxEA /usr/local]# useradd mysql -s /sbin/nologin -M
[root@LinuxEA /usr/local]# mkdir -p /data/mysql
[root@LinuxEA /usr/local]# chown -R mysql.mysql /data/mysql
[root@LinuxEA /usr/local]# /usr/local/mysql/scripts/mysql_install_db --user=mysql --datadir=/data/mysql/ --basedir=/usr/local/mysql
复制启动脚本
[root@LinuxEA /usr/local]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
[root@LinuxEA /usr/local]# systemctl enable mysqld
mysqld.service is not a native service, redirecting to /sbin/chkconfig.
Executing /sbin/chkconfig mysqld on
[root@LinuxEA /usr/local]#
安装jemalloc内存分配器
[root@LinuxEA /]# wget https://github.com/jemalloc/jemalloc/releases/download/4.2.1/jemalloc-4.2.1.tar.bz2
[root@LinuxEA /]# yum install -y gcc lsof
[root@LinuxEA /]# tar xf jemalloc-4.2.1.tar.bz2
[root@LinuxEA /]# cd jemalloc-4.2.1/
[root@LinuxEA /jemalloc-4.2.1]# ./configure
[root@LinuxEA /jemalloc-4.2.1]# make
[root@LinuxEA /jemalloc-4.2.1]# make install
授权用户:
grant all privileges on *.* to 'tb'@'%' identified by 'password';
flush privileges;
wsrep_cluster_address=”gcomm://10.0.1.49,10.10.240.113,10.0.1.61″如下:
gcomm://后的是集群成员的ip地址
wsrep_sst_auth=tb:password如下:这里的sst需要安装lsof依赖包
这个参数就是我们之前设定的用来同步的用户名和密码
wsrep_node_name=’node1′ 如下:
当前node
wsrep_node_address=’10.0.1.49′ 如下:
当前node ip地址
galera
[galera]
##https://www.percona.com/doc/percona-xtradb-cluster/5.6/wsrep-system-index.html
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
#wsrep_cluster_address="gcomm://"
wsrep_cluster_address="gcomm://10.0.1.49,10.10.240.113,10.0.1.61"
wsrep_cluster_name='cluster'
wsrep_node_address='10.0.1.49'
wsrep_node_name='node1'
#wsrep_replicate_myisam=1
####wsrep_slave_threads = 8
#wsrep_slave_threads = 16
##wsrep_provider_options="gcs.fc_limit=512"
#wsrep_provider_options="gcache.page_size=128M;gcache.size=2G;gcs.fc_limit=512;gcs.fc_factor=0.9;evs.send_window=256;evs.user_send_window=128;cert.log_conflicts=yes"
##wsrep_notify_cmd='/data/galeranotify/galeranotify.py'
#wsrep_log_conflicts=1
#wsrep_forced_binlog_format=ROW
#wsrep_drupal_282555_workaround=1
#wsrep_max_ws_size=2147483647
##wsrep_dirty_reads=0 #当值是1的时候这个节点是只读节点
##wsrep_sst_method=[mysqldump|xtrabackup|xtrabackup-v2|rsync|rsync_wan]
#wsrep_sst_method=xtrabackup-v2
wsrep_sst_method=rsync
wsrep_sst_auth=tb:password
这里需要注意的是,第一次启动使用–wsrep-new-cluster,如果此时集群中这台故障,需要修改配置文件打开:wsrep_cluster_address=”gcomm://10.0.1.49,10.10.240.113,10.0.1.61″这一项,如过其他两天数据已经和这台不同步,这需要删除目录数据后进行同步恢复并加入集群
[root@LinuxEA /data/mysql]# /etc/init.d/mysqld start --wsrep-new-cluster
做一些简单的优化:
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.db WHERE Db LIKE 'test%';
DROP DATABASE test;
UPDATE mysql.user SET password = password('abc123') WHERE user = 'root';
第二台的mariadb安装完成后,直接删掉/data/mysql下的文件,从10.0.1.49同步
[root@LinuxEA-2 /data/mysql]# rm -rf *
[root@LinuxEA-2 /data/mysql]# /etc/init.d/mysqld start
Starting MySQL.170524 17:43:41 mysqld_safe Adding '/usr/local/lib/libjemalloc.so' to LD_PRELOAD for mysqld
170524 17:43:41 mysqld_safe Logging to '/data/mysql/mysql-error.log'.
170524 17:43:41 mysqld_safe Starting mysqld daemon with databases from /data/mysql
..........SST in progress, setting sleep higher.... SUCCESS!
部分配置文件:
[galera]
##https://www.percona.com/doc/percona-xtradb-cluster/5.6/wsrep-system-index.html
wsrep_on=ON
wsrep_cluster_address="gcomm://10.0.1.49,10.10.240.113,10.0.1.61"
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_name='cluster'
wsrep_node_address='10.0.1.61'
wsrep_node_name='node2'
#wsrep_replicate_myisam=1
#wsrep_node_name='node1'
#wsrep_replicate_myisam=1
####wsrep_slave_threads = 8
#wsrep_slave_threads = 16
##wsrep_provider_options="gcs.fc_limit=512"
#wsrep_provider_options="gcache.page_size=128M;gcache.size=2G;gcs.fc_limit=512;gcs.fc_factor=0.9;evs.send_window=256;evs.user_send_window=128;cert.log_conflicts=yes"
##wsrep_notify_cmd='/data/galeranotify/galeranotify.py'
#wsrep_log_conflicts=1
#wsrep_forced_binlog_format=ROW
#wsrep_drupal_282555_workaround=1
#wsrep_max_ws_size=2147483647
##wsrep_dirty_reads=0 #当值是1的时候这个节点是只读节点
##wsrep_sst_method=[mysqldump|xtrabackup|xtrabackup-v2|rsync|rsync_wan]
#wsrep_sst_method=xtrabackup-v2
wsrep_sst_method=rsync
wsrep_sst_auth=tb:password
同样删除/data/mysql下的文件,从10.0.1.49同步
[root@LinuxEA-3 /data/mysql]# rm -rf *
[root@LinuxEA-3 /data/mysql]# /etc/init.d/mysqld start
Starting MySQL.170524 18:58:34 mysqld_safe Adding '/usr/local/lib/libjemalloc.so' to LD_PRELOAD for mysqld
170524 18:58:34 mysqld_safe Logging to '/data/mysql/mysql-error.log'.
170524 18:58:34 mysqld_safe Starting mysqld daemon with databases from /data/mysql
.....SST in progress, setting sleep higher.. SUCCESS!
[root@LinuxEA-3 /data/mysql]#
部分配置文件:
[galera]
##https://www.percona.com/doc/percona-xtradb-cluster/5.6/wsrep-system-index.html
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_address="gcomm://10.0.1.49,10.10.240.113,10.0.1.49"
#wsrep_cluster_address="gcomm://"
wsrep_cluster_name='cluster'
wsrep_node_address='10.10.240.113'
wsrep_node_name='node3'
#wsrep_replicate_myisam=1
####wsrep_slave_threads = 8
#wsrep_slave_threads = 16
##wsrep_provider_options="gcs.fc_limit=512"
#wsrep_provider_options="gcache.page_size=128M;gcache.size=2G;gcs.fc_limit=512;gcs.fc_factor=0.9;evs.send_window=256;evs.user_send_window=128;cert.log_conflicts=yes"
##wsrep_notify_cmd='/data/galeranotify/galeranotify.py'
#wsrep_log_conflicts=1
#wsrep_forced_binlog_format=ROW
#wsrep_drupal_282555_workaround=1
#wsrep_max_ws_size=2147483647
##wsrep_dirty_reads=0 #当值是1的时候这个节点是只读节点
##wsrep_sst_method=[mysqldump|xtrabackup|xtrabackup-v2|rsync|rsync_wan]
#wsrep_sst_method=xtrabackup-v2
wsrep_sst_method=rsync
wsrep_sst_auth=tb:password
三台启动完成状态:
[root@LinuxEA /data/mysql]# mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+