ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ubuntu下docker安装mongodb

ubuntu下docker安装mongodb 1.mogodb支持事务的前提1) MongoDB 版本确保 MongoDB 版本大于或等于 4.0因为事务支持是在 4.0 版本中引入的。2) 副本集配置MongoDB 必须以副本集Replica Set或者分片集群的方式运行不能是单机模式注意单节点副本集也是支持事务的即只有一个 MongoDB 实例但以副本集模式启动。2.安装docker3.单副本集安装3.1 创建目录和文件1) 宿主机-mongodb的数据存储目录mkdir /mongo/data chmod 777 /mongo/data2) 宿主机-mongodb的配置文件目录mkdir /mongo/conf chmod 777 /mongo/conf3) 宿主机-mongodb的密钥文件cd /mongo openssl rand -base64 756 keyFile chmod 400 keyFile # 一定是400不要赋权777 chown 999:999 keyFile4) 在/mongo/conf目录下生成配置文件mongod.conf# 存储配置 storage: dbPath: /data/db # 数据库文件存储路径 engine: wiredTiger # 存储引擎通常为 wiredTiger wiredTiger: engineConfig: cacheSizeGB: 1 # WiredTiger 缓存大小单位GB directoryForIndexes: true # 是否为索引使用单独目录 # 网络配置 net: port: 27017 # MongoDB 监听端口 bindIp: 0.0.0.0 # 绑定 IP 地址0.0.0.0 表示监听所有网络接口 # 安全配置 security: authorization: enabled # 是否启用认证 keyFile: /data/mongodb/keyFile # 密钥文件路径用于副本集或分片集群 # 副本集配置如果使用副本集 replication: replSetName: rs0 # 副本集名称3.2 启动MongoDB容器docker run -d --name mongo -p 27017:27017 \ -v /mongo/data:/data/db \ -v /mongo/conf/mongod.conf:/etc/mongod.conf \ -v /mongo/keyFile:/data/mongodb/keyFile \ mongo:latest mongod --auth --bind_ip_all --config /etc/mongod.conf # -e MONGO_INITDB_ROOT_USERNAMEroot -e MONGO_INITDB_ROOT_PASSWORD123456如果运行上述命令后mongodb容器处于退出状态请排查数据挂载目录权限、配置文件问题、keyFile文件问题、27017端口没有开放、容器占用系统太多资源导致系统资源不足等问题可通过docker logs mongo查看具体原因。3.3 查看存储引擎和版本# 查看mongodb版本 db.version() # 查看当前数据库的存储引擎需要root角色用户 db.serverStatus().storageEngine3.4初始化副本集和创建用户# 进入MongoDB容器 docker exec -it mongo mongosh # 初始化副本集 rs.initiate({ _id: rs0, members: [ { _id: 0, host: 172.12.112.102:27017 } ] }) # 创建管理员用户 use admin db.createUser({ user: admin, pwd: admin123456, roles: [{role: userAdminAnyDatabase, db: admin}]}) # 创建root用户 db.createUser({ user: root, pwd: 123456, roles: [{ role: root, db: admin }] }) # 验证用户 db.auth(admin, admin123456) db.auth(root, 123456)3.5 创建集合use biobank db.createUser({user: test, pwd: 123456, roles: [{role: readWrite, db: printing}]}) exit docker exec -it mongo mongosh use biobank db.auth(test, 123456)3.6 pymongo工具验证支持事务from pymongo import MongoClient from pymongo.errors import PyMongoError # 连接到 MongoDB 副本集 client MongoClient( mongodb://root:123456172.16.210.206:27017, replicaSetrs0 ) # 选择数据库和集合 db client.test_database collection db.test_collection collection2 db.test_collection2 # 创建一个会话来支持事务 with client.start_session() as session: try: # 开始事务 with session.start_transaction(): # 插入文档 collection.insert_one({_id: 1, name: Alice, age: 20}, sessionsession) collection2.insert_one({_id: 1, name: Bob, age: 25}, sessionsession) # 提交事务 session.commit_transaction() print(事务成功提交) except PyMongoError as e: # 如果发生错误中止事务 print(事务中发生错误:, e) # session.abort_transaction() finally: # 确保会话结束 session.end_session() # 关闭客户端连接 client.close()3.6 Flask-MongoEngine使用事务在 MongoDB 中事务是通过会话Session来管理的。Flask-MongoEngine 本身不直接提供事务管理但可以通过 PyMongo 的会话功能来实现。MONGODB_SETTINGS { db: biobank, host: mongodb://test:123456172.12.112.102:27017/biobank?replicaSetrs0 } # 或者 MONGODB_SETTINGS { host: 172.12.112.102, port: 27017, username: test, password: 123456, db: biobank, authSource: biobank, # 指定身份验证数据库 replicaSet: rs0, connectTimeoutMS: 5000, # 设置套接字超时时间毫秒。 socketTimeoutMS: 30000, # 设置套接字超时时间毫秒。 serverSelectionTimeoutMS: 5000, # 设置服务器选择超时时间毫秒当客户端尝试连接到 MongoDB 服务器时如果在此时间内没有找到可用的服务器将抛出异常。 retryWrites: True, # 写重试 retryReads: True # 读重试 }class SampleModel(db.Document): 样本信息表关联项目集合和患者集合 sample db.StringField() # 样本号 subject db.ReferenceField(Subject) # 关联受检者 projects db.ListField(db.ReferenceField(Project)) # 关联项目 created_at db.DateTimeField(auto_now_addTrue) updated_at db.DateTimeField(auto_nowTrue) class Subject(db.Document): 受试者集合 subject_name db.StringField(requiredTrue, max_length100) gender db.StringField(choices[male, female, unknown]) birthday db.StringField(max_length10) contact_phone db.StringField(max_length20) # 联系电话 employee db.ReferenceField(Employee) # 关联员工 created_at db.DateTimeField(auto_now_addTrue) updated_at db.DateTimeField(auto_nowTrue) class Project(db.Document): project_name db.StringField(requiredTrue, max_length100, uniqueTrue) description db.StringField(max_length500) investigator db.StringField(max_length100) # 项目负责人 created_at db.DateTimeField(auto_now_addTrue) updated_at db.DateTimeField(auto_nowTrue) def bulk_samples(dataNone): 创建样本数据 save/ create / insert param data: return: if data is None: data [] client db.connection bio_bank client.biobank session client.start_session() try: with session.start_transaction(): samples_to_create [] sample_model_fields SampleModel.get_fields() subjects, projects dict(), defaultdict(list) for item in data: if item[no] is None or len(item[no]) 0: raise ValueError(no不能为空!) sample_data {k: item[k] for k in item.keys() if k in sample_model_fields} if item.get(subject_name): if item[subject_name] not in subjects.keys(): subject_obj Subject.objects(subject_nameitem[subject_name]).first() if subject_obj is None: kwargs { subject_name: item[subject_name], contact_phone: item.get(subject_phone), gender: item[gender] if item.get(gender) in [male, female] else unknown, birthday: item.get(birthday) } subject_obj bio_bank.subject.insert_one(kwargs, sessionsession).inserted_id subjects[item[subject_name]] subject_obj sample_data.update({subject: subjects[item[subject_name]]}) if item.get(project_name): if item[project_name] not in projects.keys(): project_obj Project.objects(project_nameitem[project_name]).first() if project_obj is None: kwargs {project_name: item.get(project_name)} project_obj bio_bank.project.insert_one(kwargs, sessionsession).inserted_id projects[item[project_name]] [project_obj] sample_data.update({projects: projects[item[project_name]]}) samples_to_create.append(sample_data) bio_bank.sample_model.insert_many(samples_to_create, sessionsession) return 200, success except NotUniqueError: return 409, 样本已存在不允许重复插入 except Exception as e: return 400, str(e)4.三节点副本集安装-支持事务4.1 创建三个单副本集容器单容器方式过程和单副本集一样区别在于一点可以选择创建docker网络把三个mongo容器关联起来docker network create mongo-net # 三个容器共用一个keyFile # primary docker run -d --name mongo-primary -p 27018:27017 -v /docker/mongo-replica/mongo-primary/data:/data/db -v /docker/mongo-replica/mongo-primary/conf/mongod.conf:/etc/mongod.conf -v /docker/mongo-replica/keyFile:/data/mongodb/keyFile -e MONGO_INITDB_ROOT_USERNAMEroot -e MONGO_INITDB_ROOT_PASSWORD123456 --network mongo-net docker-0.unsee.tech/mongo:latest mongod --bind_ip_all --config /etc/mongod.conf # secondary docker run -d --name mongo-secondary1 -p 27019:27017 -v /docker/mongo-replica/mongo-secondary1/data:/data/db -v /docker/mongo-replica/mongo-secondary1/conf/mongod.conf:/etc/mongod.conf -v /docker/mongo-replica/keyFile:/data/mongodb/keyFile -e MONGO_INITDB_ROOT_USERNAMEroot -e MONGO_INITDB_ROOT_PASSWORD123456 --network mongo-net docker-0.unsee.tech/mongo:latest mongod --bind_ip_all --config /etc/mongod.conf # secondary docker run -d --name mongo-secondary2 -p 27020:27017 -v /docker/mongo-replica/mongo-secondary2/data:/data/db -v /docker/mongo-replica/mongo-secondary2/conf/mongod.conf:/etc/mongod.conf -v /docker/mongo-replica/keyFile:/data/mongodb/keyFile -e MONGO_INITDB_ROOT_USERNAMEroot -e MONGO_INITDB_ROOT_PASSWORD123456 --network mongo-net docker-0.unsee.tech/mongo:latest mongod --bind_ip_all --config /etc/mongod.confdocker compose 管理version: 3.8 services: mongo-primary: image: docker-0.unsee.tech/mongo:latest container_name: mongo_primary restart: always ports: - 27018:27017 volumes: - /docker/mongo-replica/mongo-primary/data:/data/db - /docker/mongo-replica/mongo-primary/conf/mongod.conf:/etc/mongod.conf - /docker/mongo-replica/keyFile:/data/mongodb/keyFile environment: - MONGO_INITDB_ROOT_USERNAMEroot - MONGO_INITDB_ROOT_PASSWORD123456 - TZAsia/Shanghai command: - mongod - --bind_ip_all - --config - /etc/mongod.conf - --setParameter - diagnosticDataCollectionEnabledfalse networks: - mongo-net mongo-secondary1: image: docker-0.unsee.tech/mongo:latest container_name: mongo_secondary1 restart: always ports: - 27019:27017 volumes: - /docker/mongo-replica/mongo-secondary1/data:/data/db - /docker/mongo-replica/mongo-secondary1/conf/mongod.conf:/etc/mongod.conf - /docker/mongo-replica/keyFile:/data/mongodb/keyFile environment: - MONGO_INITDB_ROOT_USERNAMEroot - MONGO_INITDB_ROOT_PASSWORD123456 - TZAsia/Shanghai command: - mongod - --bind_ip_all - --config - /etc/mongod.conf - --setParameter - diagnosticDataCollectionEnabledfalse networks: - mongo-net mongo-secondary2: image: docker-0.unsee.tech/mongo:latest container_name: mongo_secondary2 restart: always ports: - 27020:27017 volumes: - /docker/mongo-replica/mongo-secondary2/data:/data/db - /docker/mongo-replica/mongo-secondary2/conf/mongod.conf:/etc/mongod.conf - /docker/mongo-replica/keyFile:/data/mongodb/keyFile environment: - MONGO_INITDB_ROOT_USERNAMEroot - MONGO_INITDB_ROOT_PASSWORD123456 - TZAsia/Shanghai command: - mongod - --bind_ip_all - --config - /etc/mongod.conf - --setParameter - diagnosticDataCollectionEnabledfalse networks: - mongo-net networks: mongo-net: external: true # 声明使用外部已经存在的 mongo-net 网络4.2 在主节点中配置副本集# 先用容器名称初始化副本集 rs.initiate({ _id: rs0, members: [ { _id: 0, host: mongo-primary:27017, priority: 10 }, { _id: 1, host: mongo-secondary1:27017, priority: 5 }, { _id: 2, host: mongo-secondary2:27017, priority: 5 } ] }) # mongo-primary:27017配置形式外部的python程序解析不了主机因此改为ipport的形式 var cfg rs.conf(); for (var i 0; i cfg.members.length; i) { if (cfg.members[i].host mongo-primary:27017) { cfg.members[i].host 172.16.200.280:27018; } else if (cfg.members[i].host mongo-secondary1:27017) { cfg.members[i].host 172.16.200.280:27019; } else if (cfg.members[i].host mongo-secondary2:27017) { cfg.members[i].host 172.16.200.280:27020; } } // 将修改后的配置强制应用到集群 rs.reconfig(cfg);4.3 python验证是否支持事务from pymongo import MongoClient from pymongo.errors import PyMongoError # 连接到 MongoDB 副本集 client MongoClient( mongodb://root:123456172.16.210.206:27018, replicaSetrs0 ) # 选择数据库和集合 db client.test_database collection1 db.test_collection1 collection2 db.test_collection2 # 创建一个会话来支持事务 可以插入同一个_id验证事务是否回滚 with client.start_session() as session: try: # 开始事务 with session.start_transaction(): # 插入文档 collection1.insert_one({_id: 1, name: Alice2, age: 320}, sessionsession) collection2.insert_one({_id: 2, name: Bob, age: 25}, sessionsession) # 提交事务 session.commit_transaction() print(事务成功提交) except PyMongoError as e: # 如果发生错误中止事务 print(事务中发生错误:, e) # session.abort_transaction() finally: # 确保会话结束 session.end_session() # 关闭客户端连接 client.close()4.4 FastAPI测试连接mongofield_validator(MONGO_URI, modebefore) def assemble_mongo_connection(cls, v: Optional[str], info: ValidationInfo) - Any: if isinstance(v, str): return v values info.data env values.get(APP_ENV, development) if env aly_production: return None elif env lan_production or env development: # 使用多节点种子地址保证高可用 nodes 172.16.210.100:27018,172.16.210.100:27019,172.16.210.100:27020 user root password 123456 db biobank auth_source admin replica_set rs0 # 拼装出完整的副本集连接字符串 return fmongodb://{user}:{password}{nodes}/{db}?authSource{auth_source}replicaSet{replica_set} return None
返回列表