基于docker的mongodb安装以及PHP使用
说明:用docker基于单服务器,虚拟多个服务器的方案,
以下是两个config服务器,两个分片,以及每个分片有一个副本的方案
这里关于给mongodb设置远程密码的问题,我采取了用两个compser文件来解决的方式
也就是先不给mongodb配置keyfile(默认就是这样的),任何人都可以连到mongodb,且有权限访问和创建database。
启动docker-compose-no-auth.yml后,创建admin账号和密码。
已经创建了管理员帐号了,然后再来设置mongodb需要账号密码访问,其他子账号都可以由admin去分配。
停掉之前的docker-compose-no-auth.yml
然后再次启动docker-compose-auth.yml
这样通过依次配置两个compose文件来解决设置mongodb远程连接的问题。
如果你有更好的方式,请给我留言,非常感谢!
1、安装docker
#前往阿里云,搜索<容器镜像服务>开启服务 #安装参考阿里云文档
https://yq.aliyun.com/articles/110806?spm=5176.8351553.0.0.320d19912gmHZ6 #开启镜像加速使用阿里云镜像服务器
#进入阿里云<容器镜像服务> -- <镜像中心> -- <镜像加速器>
#按里面的步骤添加配置
2、安装docker-composer
#参考官方文档https://docs.docker.com/compose/install/
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
3、启动docker-compose文件
首先启动,这时还没有设置远程账号密码
docker-compose-no-auth.yml
version: '3'
services: # config服务器一
config_one:
container_name: config_one
image: mongo:4.1.11
ports:
- 27051:27019
volumes:
- ./config_one/db:/data/db
- ./config_one/configdb:/data/configdb
command: --configsvr --replSet "rs_config" --bind_ip_all
restart: always # config服务器二
config_two:
container_name: config_two
image: mongo:4.1.11
ports:
- 27052:27019
volumes:
- ./config_two/db:/data/db
- ./config_two/configdb:/data/configdb
command: --configsvr --replSet "rs_config" --bind_ip_all
restart: always # 分片一的副本a
shard_one_a:
container_name: shard_one_a
image: mongo:4.1.11
ports:
- 27011:27018
volumes:
- ./shard_one_a/db:/data/db
- ./shard_one_a/configdb:/data/configdb
- ./shard_one_a/backup:/data/backup
command: --shardsvr --replSet "rs_shard_one_cluster" --bind_ip_all
restart: always
depends_on:
- config_one
- config_two # 分片二的副本a
shard_two_a:
container_name: shard_two_a
image: mongo:4.1.11
ports:
- 27012:27018
volumes:
- ./shard_two_a/db:/data/db
- ./shard_two_a/configdb:/data/configdb
- ./shard_two_a/backup:/data/backup
command: --shardsvr --replSet "rs_shard_two_cluster" --bind_ip_all
restart: always
depends_on:
- config_one
- config_two # 分片一的副本b
shard_one_b:
container_name: shard_one_b
image: mongo:4.1.11
ports:
- 27021:27018
volumes:
- ./shard_one_b/db:/data/db
- ./shard_one_b/configdb:/data/configdb
- ./shard_one_b/backup:/data/backup
command: --shardsvr --replSet "rs_shard_one_cluster" --bind_ip_all
restart: always
depends_on:
- config_one
- config_two # 分片二的副本b
shard_two_b:
container_name: shard_two_b
image: mongo:4.1.11
ports:
- 27022:27018
volumes:
- ./shard_two_b/db:/data/db
- ./shard_two_b/configdb:/data/configdb
- ./shard_two_b/backup:/data/backup
command: --shardsvr --replSet "rs_shard_two_cluster" --bind_ip_all
restart: always
depends_on:
- config_one
- config_two # mongos服务器一
mongos_one:
container_name: mongos-one
image: mongo:4.1.11
ports:
- 27001:27017
volumes:
- ./mongos_one/db:/data/db
- ./mongos_one/configdb:/data/configdb
entrypoint: mongos
command: --configdb rs_config/192.168.10.188:27051,192.168.10.188:27052 --bind_ip_all
depends_on:
- shard_one_a
- shard_two_a # mongos服务器二
mongos_two:
container_name: mongos-two
image: mongo:4.1.11
ports:
- 27002:27017
volumes:
- ./mongos_two/db:/data/db
- ./mongos_two/configdb:/data/configdb
entrypoint: mongos
command: --configdb rs_config/192.168.10.188:27051,192.168.10.188:27052 --bind_ip_all
depends_on:
- shard_one_b
- shard_two_b
4、配置分片,添加管理员
# 连接到任意一台配置服务器,初始化配置服副本
docker exec -it config_one /bin/bash
mongo --host localhost --port 27019
rs.initiate({
_id: "rs_config",
configsvr: true,
members: [
{ _id : 0, host : "172.19.60.174:27101" },
{ _id : 1, host : "172.19.60.175:27101" }
]
});
rs.status() # 连接到分片一,配置副本a、b
docker exec -it shard_one_a /bin/bash
mongo --host localhost --port 27018 rs.initiate({
_id: "rs_shard_one_cluster",
members: [
{ _id : 0, host : "172.19.60.174:27201" },
{ _id : 1, host : "172.19.60.175:27201" }
]
});
rs.status() # 连接到分片二,配置副本a、b
docker exec -it shard_two_a /bin/bash
mongo --host localhost --port 27018 rs.initiate({
_id: "rs_shard_two_cluster",
members: [
{ _id : 0, host : "172.19.60.174:27202" },
{ _id : 1, host : "172.19.60.175:27202" }
]
});
rs.status() # 连接到mongos服务器,添加分片
docker exec -it mongos-one /bin/bash
mongo --host localhost --port 27017
sh.addShard("rs_shard_one_cluster/172.19.60.174:27201,172.19.60.175:27201");
sh.addShard("rs_shard_two_cluster/172.19.60.174:27202,172.19.60.175:27202");
sh.status() docker exec -it mongos-two /bin/bash
mongo --host localhost --port 27017
sh.addShard("rs_shard_one_cluster/172.19.60.174:27201,172.19.60.175:27201");
sh.addShard("rs_shard_two_cluster/172.19.60.174:27202,172.19.60.175:27202");
sh.status() //为数据库启动分片
sh.enableSharding("test")
//在需要分片的集合上对分片键建索引
//如果集合是空的,可以不创建索引直接进行下一步的分片会自动创建索引
//如果集合不为空,必须为分片建创建索引才行
db.test.ensureIndex({"id":1}) //设置分片键
//其中第一种是基于hash的分片,第二种为基于值的分片
sh.shardCollection( "test.student", { "id" : "hashed" } )
sh.shardCollection("test.teacher", { "id" : 1 } ) //查看片的状态
sh.status();
//查看片状态(完整版);
printShardingStatus(db.getSisterDB("config"),1);
//查看所有的分片服务器状态
db.stats(); //测试分片数据
use test
for (var i = 1; i <= 1000; i++) {
db.student.insert( { "id" : i , "name": "student" + i } )
} //分别连接到两个mongos, 分片一主副节点,分片二主副节点,查看是否数据都有
use test
db.student.find().sort({id:1}); //生成管理员账号
docker exec -it mongos-one /bin/bash
mongo --host localhost --port 27017
use admin
db.runCommand({
"createUser" : "root",
"pwd" : "root^mongo",
"customData" : { },
"roles" : [
{
"role" : "dbAdminAnyDatabase",
"db" : "admin"
},
{
"role" : "readWriteAnyDatabase",
"db" : "admin"
},
{
"role" : "root",
"db" : "admin"
}
]
});
5、生成keyfile
//生成keyfile
openssl rand -base64 756 > mongo-keyfile.jks
chmod 400 mongo-keyfile.jks
6、配置密钥,使mongodb访问需要带密码
带keyfile的docker-compose-auth.yml
version: '3'
services: # config服务器一
config_one:
container_name: config_one
image: mongo:4.1.11
ports:
- 27051:27019
volumes:
- ./config_one/db:/data/db
- ./config_one/configdb:/data/configdb
- ./mongo-keyfile.jks:/data/configdb/mongo-keyfile.jks
command: --keyFile /data/configdb/mongo-keyfile.jks --configsvr --replSet "rs_config" --bind_ip_all
restart: always # config服务器二
config_two:
container_name: config_two
image: mongo:4.1.11
ports:
- 27052:27019
volumes:
- ./config_two/db:/data/db
- ./config_two/configdb:/data/configdb
- ./mongo-keyfile.jks:/data/configdb/mongo-keyfile.jks
command: --keyFile /data/configdb/mongo-keyfile.jks --configsvr --replSet "rs_config" --bind_ip_all
restart: always # 分片一的副本a
shard_one_a:
container_name: shard_one_a
image: mongo:4.1.11
ports:
- 27011:27018
volumes:
- ./shard_one_a/db:/data/db
- ./shard_one_a/configdb:/data/configdb
- ./shard_one_a/backup:/data/backup
- ./mongo-keyfile.jks:/data/configdb/mongo-keyfile.jks
command: --keyFile /data/configdb/mongo-keyfile.jks --shardsvr --replSet "rs_shard_one_cluster" --bind_ip_all
restart: always
depends_on:
- config_one
- config_two # 分片二的副本a
shard_two_a:
container_name: shard_two_a
image: mongo:4.1.11
ports:
- 27012:27018
volumes:
- ./shard_two_a/db:/data/db
- ./shard_two_a/configdb:/data/configdb
- ./shard_two_a/backup:/data/backup
- ./mongo-keyfile.jks:/data/configdb/mongo-keyfile.jks
command: --keyFile /data/configdb/mongo-keyfile.jks --shardsvr --replSet "rs_shard_two_cluster" --bind_ip_all
restart: always
depends_on:
- config_one
- config_two # 分片一的副本b
shard_one_b:
container_name: shard_one_b
image: mongo:4.1.11
ports:
- 27021:27018
volumes:
- ./shard_one_b/db:/data/db
- ./shard_one_b/configdb:/data/configdb
- ./shard_one_b/backup:/data/backup
- ./mongo-keyfile.jks:/data/configdb/mongo-keyfile.jks
command: --keyFile /data/configdb/mongo-keyfile.jks --shardsvr --replSet "rs_shard_one_cluster" --bind_ip_all
restart: always
depends_on:
- config_one
- config_two # 分片二的副本b
shard_two_b:
container_name: shard_two_b
image: mongo:4.1.11
ports:
- 27022:27018
volumes:
- ./shard_two_b/db:/data/db
- ./shard_two_b/configdb:/data/configdb
- ./shard_two_b/backup:/data/backup
- ./mongo-keyfile.jks:/data/configdb/mongo-keyfile.jks
command: --shardsvr --replSet "rs_shard_two_cluster" --keyFile /data/configdb/mongo-keyfile.jks --bind_ip_all
restart: always
depends_on:
- config_one
- config_two # mongos服务器一
mongos_one:
container_name: mongos-one
image: mongo:4.1.11
ports:
- 27001:27017
volumes:
- ./mongos_one/db:/data/db
- ./mongos_one/configdb:/data/configdb
- ./mongo-keyfile.jks:/data/configdb/mongo-keyfile.jks
entrypoint: mongos
command: --keyFile /data/configdb/mongo-keyfile.jks --configdb rs_config/192.168.10.188:27051,192.168.10.188:27052 --bind_ip_all
depends_on:
- shard_one_a
- shard_two_a # mongos服务器二
mongos_two:
container_name: mongos-two
image: mongo:4.1.11
ports:
- 27002:27017
volumes:
- ./mongos_two/db:/data/db
- ./mongos_two/configdb:/data/configdb
- ./mongo-keyfile.jks:/data/configdb/mongo-keyfile.jks
entrypoint: mongos
command: --keyFile /data/configdb/mongo-keyfile.jks --configdb rs_config/192.168.10.188:27051,192.168.10.188:27052 --bind_ip_all
depends_on:
- shard_one_b
- shard_two_b
注意mongo-keyfile.jks放的目录位置,最后再次启动docker,这时候的mongodb访问就需要账号密码了
docker-compose -f docker-compose-auth.yml up -d
7、安装php mongodb扩展
扩展源码下载地址:http://pecl.php.net/package/mongodb wget -c https://pecl.php.net/get/mongodb-1.5.4.tgz tar -zxvf mongodb-1.5.4.tgz cd mongodb-1.5.4 /www/server/php/72/bin/phpize ./configure --with-php-config=/www/server/php/72/bin/php-config make && make install vim /www/server/php/72/etc/php.ini extension = /www/server/php/72/lib/php/extensions/no-debug-non-zts-20170718/mongodb.so
8、封装mongodb使用类
我这里开始使用的thinkphp5官方给的mongodb连接库
参考:
https://packagist.org/packages/noprom/think-mongo-extend
https://www.kancloud.cn/manual/thinkphp5/167865
后来发现tp5官方的库,太难用了,做不了复杂的条件查询,于是自己写了一个,
最后面有使用的示例,php mongodb官方有更多很详细的复杂查询的示例,使用文档参考:
Connection.php
<?php namespace app\util\mongo; use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\Command;
use MongoDB\Driver\Query;
use MongoDB\Driver\Manager; class Connection
{
protected $config = [];
protected $server = [];
protected $manager; public function __construct(array $config = [])
{
if (!class_exists('\MongoDB\Driver\Manager')) {
throw new Exception('require mongodb > 1.0');
} $this->config = config('mongo');
if (!empty($config)) {
$this->config = array_merge($this->config, $config);
} if (!isset($this->manager)) {
$index = mt_rand(0, $this->config['master_num'] - 1);
$server = $this->config['servers'][$index];
$this->server = $server;
$this->manager = new Manager("mongodb://".$server['username'].":".$server['password']."@".$server['host'].":".$server['port']."/".$server['database']);
}
} public function query($table, $filter, $options) {
$namespace = $this->server['database'].'.'.$table; $query = new Query($filter, $options);
$rows = $this->manager->executeQuery($namespace, $query); $rows->setTypeMap(['root' => 'array', 'document' => 'array', 'array' => 'array']);
return $rows->toArray();
} public function insert($table, $data) {
$namespace = $this->server['database'].'.'.$table; $bulk = new BulkWrite();
$bulk->insert($data);
$result = $this->manager->executeBulkWrite($namespace, $bulk); return $result->getInsertedCount();
} public function update($table, $filter, $data, $options = []) {
$namespace = $this->server['database'].'.'.$table; $bulk = new BulkWrite();
$bulk->update($filter, $data, $options);
$result = $this->manager->executeBulkWrite($namespace, $bulk); return $result->getMatchedCount();
} public function delete($table, $filter, $options = []) {
$namespace = $this->server['database'].'.'.$table; $bulk = new BulkWrite();
$bulk->delete($filter, $options);
$result = $this->manager->executeBulkWrite($namespace, $bulk); return $result->getDeletedCount();
} public function command($cmd) {
$namespace = $this->server['database'];
$rows = $this->manager->executeCommand($namespace, $cmd);
$rows->setTypeMap(['root' => 'array', 'document' => 'array', 'array' => 'array']);
return $rows->toArray();
} function aggregate($table, $pipeline){
$cmdOption = [
'aggregate' => $table,
'pipeline' => $pipeline,
'cursor' => new \stdClass(),
];
$cmd = new Command($cmdOption);
return $this->command($cmd);
}
}
Mongo.php
<?php
namespace app\util\mongo; /**
* Class Db
* @package think
* @method Query cache(mixed $key = null , integer $expire = null) static 设置查询缓存
* @method mixed value(string $field) static 获取某个字段的值
* @method array column(string $field, string $key = '') static 获取某个列的值
* @method Query view(mixed $join, mixed $field = null, mixed $on = null, string $type = 'INNER') static 视图查询
* @method mixed find(mixed $data = null) static 查询单个记录
* @method mixed select(mixed $data = null) static 查询多个记录
* @method void commit() static 用于非自动提交状态下面的查询提交
* @method void rollback() static 事务回滚
* @method boolean batchQuery(array $sqlArray) static 批处理执行SQL语句
* @method string getLastInsID($sequence = null) static 获取最近插入的ID
*/ class Mongo
{
/**
* @var Connection[] 数据库连接实例
*/
private static $instance = []; public static function connect($config = []) { if (empty($config)) {
$config = config('mongo');
} $name = md5(serialize($config));
if (!isset(self::$instance[$name])) {
self::$instance[$name] = new Connection($config);
} return self::$instance[$name];
} /**
* 调用驱动类的方法
* @access public
* @param string $method 方法名
* @param array $params 参数
* @return mixed
*/
public static function __callStatic($method, $params)
{
return call_user_func_array([self::connect(), $method], $params);
}
}
MyExample.php
$cmd = [
['$match' => ["user_id" => ['$eq' => intval($user_id)]]],
['$project' => [
"user_id" => 1,
"book_author" => 1,
"book_sub_type" => ['$filter' => ['input' => '$book_sub_type', 'as' => 'item', 'cond' => ['$eq' => ['$$item.sex', intval($sex)]]]],
"book_type" => ['$filter' => ['input' => '$book_type', 'as' => 'item', 'cond' => ['$eq' => ['$$item.sex', intval($sex)]]]],
]],
['$project' => [
"user_id" => 1,
"book_author" => ['$slice' => ['$book_author', $tag_author_size]],
"book_sub_type" => ['$slice' => ['$book_sub_type', $tag_size]],
"book_type" => ['$slice' => ['$book_type', $tag_size]],
]],
];
$tags = Mongo::connect()->aggregate('user_tags', $cmd);
基于docker的mongodb安装以及PHP使用的更多相关文章
- ActiveMQ此例简单介绍基于docker的activemq安装与集群搭建
ActiveMQ拓展连接 此例简单介绍基于Docker的activemq安装与集群搭建 一 :安装 1.获取activemq镜像 docker pull webcenter/activemq 2.启动 ...
- Jenkins - 基于 Docker 的 Jenkins 安装
概述 安装 Jenkins 基于 Docker 这个有点 水一发 的性质... 场景 学习 Jenkins 第一步, 当然是安装 但是 安装的方法 很多 Jenkins 是基于 Java 的 所以是个 ...
- 基于docker registry镜像安装私服docker hub
采用docker registry镜像安装docker私服,通过https://hub.docker.com/_/registry链接搜索registry镜像 1.输入命令:docker pull r ...
- 基于Docker的MindSpore安装与使用基础介绍
技术背景 MindSpore是一款新一代AI开源计算框架,其特色在于:创新编程范式,AI科学家和工程师更易使用,便于开放式创新:该计算框架可满足终端.边缘计算.云全场景需求,能更好保护数据隐私:可开源 ...
- 喵星之旅-狂奔的兔子-基于docker的rabbitmq安装
docker安装参考:喵星之旅-狂奔的兔子-docker安装和基本使用 一.查询镜像名称 由于我们要安装的是有web管理页面的,不能直接拉取,需要指定版本. 登录docker仓库查询:https:// ...
- 基于Docker安装常用软件
基于Docker安装常用软件 本实验介绍如何基于Docker安装常用的软件,具体包括: Ubuntu Cetnos Nginx Node.js PHP MySQL Tomcat Redis Mongo ...
- 基于 debian 操作系统的 docker 镜像,安装 vim
基于 debian 操作系统的 docker 镜像,安装 vim,步骤: apt-get update apt-get install vim 注意: 直接运行步骤2,可能会报错: Reading p ...
- zabbix基于docker安装
centos的版本 # cat /etc/redhat-release CentOS Linux release (Core) docker的安装 配置yum源 # vim /etc/yum.repo ...
- 基于【 Docker】四 || Docker常用镜像安装
一.nginx安装 1.拉取镜像:docker pull nginx 2.启动容器:docker run -d -p 80:80 nginx 3.查看nginx:ps aux | grep 'ngin ...
随机推荐
- 【java】简介(一)
应用:web后端开发.android-app开发.大数据应用开发 学习:java会过时,但程序设计的思想不会过时 特点:1.面向对象,跨平台,语法比c++简单 2.以字节码的形式运行在虚拟机上 3.自 ...
- MapReduce shuffle的过程分析
shuffle阶段其实就是多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点上. Map端: 1.在map端首先接触的是InputSplit,在InputSplit中含有D ...
- Intellij IDEA导入JAVA项目并启动(哈哈哈,天天都有人问)
最近有很多同学,竟然不知道如何使用Intellij IDEA打开Java项目并启动 现在来讲一下,希望不要忘记了 1.打开IDEA开机页面 Maven项目 2.Maven项目是以pom文件引入各项ja ...
- 怎样在VMware虚拟机中使用安装并设置Ubuntu系统
1 2 3 4 5 6 7 分步阅读 Ubuntu 系统是一款优秀的.基于GNU/Linux 的平台的桌面系统. 当然,目前为止很多应用程序还完全不能允许运行在 Ubuntu 系统上,而且 Ubunt ...
- <JavaScript>谈谈javascript语法里一些难点问题(一)
1) 引子 前不久我建立的技术群里一位MM问了一个这样的问题,她贴出的代码如下所示: var a = 1; function hehe() { window.alert(a); var a = ...
- Android-Handler消息机制实现原理)(转)
Android-Handler消息机制实现原理 一.消息机制流程简介 在应用启动的时候,会执行程序的入口函数main(),main()里面会创建一个Looper对象,然后通过这个Looper对象开 ...
- HTM概述
Html: Hyper Text Markup Language 超文本标记语言 超文本: 超出纯文本的范畴 标记语言: 标记其实就是标签 标签的格式: <标签名称>
- ASP.NET MVC 3 Razor 多国语言参考解决方案
http://www.cnblogs.com/think8848/archive/2011/03/20/1989376.html
- 机器阅读理解综述Neural Machine Reading Comprehension Methods and Trends(略读笔记)
标题:Neural Machine Reading Comprehension: Methods and Trends 作者:Shanshan Liu, Xin Zhang, Sheng Zhang, ...
- JAVA 基础编程练习题41 【程序 41 猴子分桃】
41 [程序 41 猴子分桃] 题目:海滩上有一堆桃子,五只猴子来分.第一只猴子把这堆桃子凭据分为五份,多了一个,这只猴子把 多的一个扔入海中,拿走了一份.第二只猴子把剩下的桃子又平均分成五份,又多了 ...