數據庫應用(Mysql、Mongodb、Redis、Memcached、CouchDB、Cassandra)


目前,主流數據庫包括關系型(SQL)和非關系型(NoSQL)兩種。

關系數據庫是建立在關系模型基礎上的數據庫,借助於集合代數等數學概念和方法來處理數據庫中的數據,支持復雜的事物處理和結構化查詢。代表實現有MySQL、Oracle、PostGreSQL、MariaDB、SQLServer等。

非關系數據庫是新興的數據庫技術,它放棄了傳統關系型數據庫的部分強一致性限制,帶來性能上的提升,使其更適用於需要大規模並行處理的場景。非關系型數據庫是關系型數據庫的良好補充,代表產品有MongoDB、Memcached、CouchDB、Cassandra等。

MySQL

MySQL是全球最流行的開源的開源關系數據庫軟件之一,因為其高性能、成熟可靠和適應性而得到廣泛應用。MySQL目前在不少大規模網站和應用中被使用。

使用官方鏡像可以快速啟動一個MySQL Server實例,如下所示:

$ docker run --name hi-mysql -e MYSQL_ROOT_PASSWORD=123 -d mysql:latest

e6cb906570549812c798b7b3ce46d669a8a4e8ac62a3f3c8997e4c53d16301b6

以上指令中的hi-mysql是容器名稱,123為數據庫的root密碼。

使用docker ps指令可以看到現在運行中的容器:

$ docker ps

CONTAINER ID  IMAGE  COMMAND                CREATED       STATUS       PORTS     NAMES

e6cb90657054  mysql  "docker-entrypoint.sh" 4 minutes ago Up 3 minutes 3306/tcp  hi-mysql

當然,還可以使用--link標簽將一個應用容器連接至MySQL容器:

$ docker run --name some-app --link some-mysql:mysql -d application-that-uses-mysql

MySQL服務的標准端口是3306,用戶可以通過CLI工具對配置進行修改:

$ docker run -it --link some-mysql:mysql --rm mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P "$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'

官方MySQL鏡像還可以作為客戶端,連接非Docker或者遠程的MySQL實例:

$ docker run -it --rm mysql mysql -hsome.mysql.host -usome-mysql-user -p

1.系統與日志訪問

用戶可以使用docker exec指令調用內部系統中的bash shell,以訪問容器內部系統:

$ docker exec -it some-mysql bash

MySQL Server日志可以使用docker logs指令查看:

$ docker logs some-mysql

2.使用自定義配置文件

如果用戶希望使用自定義MySQL配置,則可以創建一個目錄,內置cnf配置文件,然后將其掛載至容器的/etc/mysql/conf.d目錄。

比如,自定義配置文件為/my/custom/config-file.cnf,則可以使用以下指令:

$ docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

這是新的容器some-mysql啟動后,就會結合使用/etc/mysql/my.cnf和/etc/mysql/conf.d/config-file.cnf兩個配置文件。

3.脫離cnf文件進行配置

很多的配置選項可以通過標簽(flags)傳遞至mysqld進程。這樣用戶就可以脫離cnf配置文件,對容器進行彈性的定制。

比如,用戶需要改變默認編碼方式,將所有表格的編碼方式修改為uft8mb4,則可以使用以下指令:

$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

如果需要查看可用選項的完整列表,可以執行:

$ docker run -it --rm mysql:tag --verbose --help

MongoDB

MongoDB是一款可擴展、高性能的開源文檔數據庫,是當今最流行的NoSQL數據庫軟件之一。它采用C++開發,支持復雜的數據類型和強大的查詢語言,提供了關系數據庫的絕大部分功能。由於MongoDB高性能、易部署、易使用等特點,已經在很多領域都得到了廣泛的應用。

使用官方鏡像

用戶可以使用docker run指令直接運行官方mongodb鏡像:

$ docker run --name mongo-container -d mongo

ade2b5036f457a6a2e7574fd68cf7a3298936f27280833769e93392015512735

之后,可以通過docker ps指令查看正在運行的mongo-container容器的容器ID:

$ docker ps

CONTAINER ID IMAGE COMMAND                CREATED     STATUS      PORTS NAMES

ade2b5036f45 mongo "/entrypoint.sh mongo" 1 hours ago Up 22 hours 27017/tcp  mongo-container

在此mongo容器啟動一個bash進程,並通過mongo指令啟動mongodb交互命令行,再通過db.stats()指令查看數據庫狀態:

$ docker exec -it ade2b5036f45 sh

# mongo
MongoDB shell version: 3.2.6
connecting to: test
> show dbs
local  0.000GB
> db.stats()
{
"db" : "test",
"collections" : 1,
"objects" : 1,
"avgObjSize" : 39,
"dataSize" : 39,
"storageSize" : 16384,
"numExtents" : 0,
"indexes" : 1,
"indexSize" : 16384,
"ok" : 1
}

這里用戶可以通過env指令查看環境變量的配置:

root@ade2b5036f45:/bin# env
HOSTNAME=ade2b5036f45
MONGO_VERSION=3.2.6
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
GPG_KEYS=DFFA3DCF326E302C4787673A01C4E7FAAAB2461C     42F3E95A2C4F08279C4960ADD
68FA50FEA312927
PWD=/bin
SHLVL=1
HOME=/root
MONGO_MAJOR=3.2
GOSU_VERSION=1.7
_=/usr/bin/env
OLDPWD=/

鏡像默認暴露了mongodb的服務端口:27017,可以通過該端口訪問服務。

1.連接mongodb容器

使用--link參數,連接新建的mongo-container容器:

$ docker run -it --link mongo-container:db alpine sh

/ # ls

進入alpine系統容器后,用戶可以使用ping指令測試db容器的連通性:

/ # ping db

2.直接使用mongo cli指令

如果想直接在宿主機器上使用mongodb鏡像,可以在docker run指令后面加入entrypoint指令,這樣就可以非常方便的直接進入mongo cli了。

$ docker run -it --link mongo-container:db --entrypoint mongo mongo --host db

> db.version();
3.2.6
>  db.stats();
{
"db" : "test",
"collections" : 0,
"objects" : 0,
"avgObjSize" : 0,
"dataSize" : 0,
"storageSize" : 0,
"numExtents" : 0,
"indexes" : 0,
"indexSize" : 0,
"fileSize" : 0,
"ok" : 1
}
> show dbs
local  0.000GB

最后,還可以使用--storageEngine參數來設置儲存引擎

$ docker run --name mongo-container -d mongo --storageEngine wiredTiger

使用自定義Dockerfile

第一步:准備工作。

新建項目目錄,並在根目錄新建Dockerfile,內容如下:

#設置從用戶之前創建的sshd鏡像繼承。
FROM sshd
MAINTAINER docker_user (user@docker.com)
RUN apt-get update && \
apt-get install -y mongodb pwgen && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
#創建mongodb存放數據文件的文件夾
RUN mkdir -p /data/db
VOLUME /data/db
ENV AUTH yes
#添加腳本
ADD run.sh /run.sh
ADD set_mongodb_password.sh /set_mongodb_password.sh
RUN chmod 755 ./*.sh
EXPOSE 27017
EXPOSE 28017
CMD ["/run.sh"]

新建set_mongodb_password.sh腳本。此腳本主要負責配置數據庫的用戶名和密碼:

#!/bin/bash
#這個腳本主要是用來設置數據庫的用戶名和密碼。
#判斷是否已經設置過密碼。
if [ -f /.mongodb_password_set ]; then
echo "MongoDB password already set!"
exit 0
fi
/usr/bin/mongod --smallfiles --nojournal &
PASS=${MONGODB_PASS:-$(pwgen -s 12 1)}
_word=$( [ ${MONGODB_PASS} ] && echo "preset" || echo "random" )
RET=1
while [[ RET -ne 0 ]]; do
echo "=> Waiting for confirmation of MongoDB service startup"
sleep 5
mongo admin --eval "help" >/dev/null 2>&1
RET=$?
done
#通過docker logs + id可以看到下面的輸出。
echo "=> Creating an admin user with a ${_word} password in MongoDB"
mongo admin --eval "db.addUser({user: 'admin', pwd: '$PASS', roles:
[ 'userAdminAnyDatabase', 'dbAdminAnyDatabase' ]});"
mongo admin --eval "db.shutdownServer();"
echo "=> Done!"
touch /.mongodb_password_set
echo "========================================================================"
echo "You can now connect to this MongoDB server using:"
echo ""
echo "    mongo admin -u admin -p $PASS --host --port "
echo ""
echo "Please remember to change the above password as soon as possible!"
echo "========================================================================"

新建run.sh,此腳本是主要的mongodb啟動腳本:

#!/bin/bash
if [ ! -f /.mongodb_password_set ]; then
/set_mongodb_password.sh
fi
if [ "$AUTH" == "yes" ]; then
#這里可以自己設定Mongodb的啟動參數。
export mongodb='/usr/bin/mongod --nojournal --auth --httpinterface --rest'
else
export mongodb='/usr/bin/mongod --nojournal --httpinterface --rest'
fi
if [ ! -f /data/db/mongod.lock ]; then
eval $mongodb
else
export mongodb=$mongodb' --dbpath /data/db'
rm /data/db/mongod.lock
mongod --dbpath /data/db --repair && eval $mongodb
fi

第二步,使用docker build指令構建鏡像:

$ docker build  -t mongodb-image .

第三步,啟動后台容器,並分別映射27017和28017端口到本地:

$ docker run -d -p 27017:27017 -p 28017:28017 mongodb

通過docker logs來查看默認的admin帳戶密碼:

$ docker logs sa9

=======================================================================
You can now connect to this MongoDB server using:
mongo admin -u admin -p 5elsT6KtjrqV --host --port
Please remember to change the above password as soon as possible!
=======================================================================

屏幕輸出中的5elsT6KtjrqV就是admin用戶的密碼。

也可以利用環境變量在容器啟動時指定密碼:

$  docker run -d -p 27017:27017 -p 28017:28017 -e MONGODB_PASS="mypass" mongodb

甚至,設定不需要密碼即可訪問:

$  docker run -d -p 27017:27017 -p 28017:28017 -e AUTH=no mongodb

同樣,也可以使用-v參數來映射本地目錄到容器。

Redis

Redis是一個開源(BSD許可)的基於內存的數據結構存儲系統,可以用作數據庫、緩存和消息中間件。

通過docker run指令可以直接啟動一個redis-container容器:

$ docker run --name redis-container -d redis

6f7d16f298e9c505f35ae28b61b4015877a5b0b75c60797fa4583429e4a14e24

之后可以通過docker ps指令查看正在運行的redis-container容器的容器ID:

$ docker ps

CONTAINER ID IMAGE COMMAND                CREATED        STATUS        PORTS        NAMES

6f7d16f298e9 redis "docker-entrypoint.sh" 32 seconds ago Up 31 seconds 6379/tcp   redis-container

在此redis容器啟動bash,並查看容器的運行時間和內存狀況:

$ docker exec -it 6f7d16f298e9 bash

root@6f7d16f298e9:/data# uptime
12:26:19 up 20 min,  0 users,  load average: 0.00, 0.04, 0.10
root@6f7d16f298e9:/data# free
total       used       free     shared    buffers     cached
Mem:       1020096     699280     320816     126800      50184     527260
-/+ buffers/cache:     121836     898260
Swap:      1181112          0    1181112

同樣可以通過env指令查看環境變量的配置:

root@6f7d16f298e9:/data# env
HOSTNAME=6f7d16f298e9
REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.0.7.tar.gz
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/data
SHLVL=1
HOME=/root
REDIS_DOWNLOAD_SHA1=e56b4b7e033ae8dbf311f9191cf6fdf3ae974d1c
REDIS_VERSION=3.0.7
GOSU_VERSION=1.7
_=/usr/bin/env

也可以通過ps指令查看當前容器運行的進程信息:

root@6f7d16f298e9:/data# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
redis        1     0   0 12:16 ?        00:00:02 redis-server *:6379
root        30     0   0 12:51 ?        00:00:00 sh
root        39    30   0 12:52 ?        00:00:00 ps -ef

1.連接redis容器

用戶可以使用--link參數,連接創建的redis-container容器:

$ docker run -it --link redis-container:db alpine sh

/ # ls

進入alpine系統容器后,可以使用ping指令測試redis容器:

/ # ping db

還可以使用nc指令(即NetCat)檢測redis服務的可用性:

/ # nc db 6379

官方鏡像內也自帶了redis客戶端,可以使用以下指令直接使用:

$ docker run -it --link redis-container:db --entrypoint redis-cli redis -h db

db:6379> ping
PONG
db:6379> set 1 2
OK
db:6379> get 1
"2"

2.使用自定義配置

可以通過數據卷實現自定義redis配置,如下所示:

$ docker run -v /myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf --name myredis redis redis-server /usr/local/etc/redis/redis.conf

Memcached

Memcached是一個高性能、分布式的開源內存對象緩存系統。Memcached守護進程基於C語言實現,基於libevent的事件處理可以實現很高的性能。需要注意的是,由於數據僅存在於內存中,因此重啟Memcached或重啟操作系統會導致數據全部丟失

可以直接通過官方提供的memcached鏡像運行一個memcached-container容器:

$ docker run --name memcached-container -d memcached

94e957b52be9a254954cddd23d64ba520493519a19c2e548b4e3dd7f41475b2a

在docker run指令中可以設定memcached server使用的內存大小:

$ docker run --name memcached-container-2 -d memcached memcached -m 64

bde9544643ac2a43945322c9bde76342dfc55db12875973da83408a8d239f94c

以上指令會將memcached server的內存使用量設置為64MB。

此時,用戶可以在宿主機器直接telnet測試訪問memcached容器,並直接輸入客戶端命令:

$ telnet 192.168.99.100 11211
Trying 192.168.99.100...
Connected to 192.168.99.100.
Escape character is '^]'.
stats
STAT pid 1
STAT uptime 19
STAT time 1462972021
STAT version 1.4.25
...
END

CouchDB

CouchDB是一款面向文檔的NoSQL數據庫,以JSON格式存儲數據。它兼容ACID,可以用於存儲網站的數據與內容,以及提供緩存等。CouchDB里文檔域(Field)都是以鍵值對的形式存儲的,對數據的每次修改都會得到一個新的文檔修訂號。CouchDB側重於AP(可用性和分區容忍度)。相比之下,MongoDB側重於CP(一致性和分區容忍度)。

可以直接使用docker run指令運行官方鏡像,如下所示:

$ docker run -d --name couchdb-container couchdb

50badad3e71da22b77bfd5522b27aa77299b649560254343d4a0c80c52a37c36

這個鏡像中CouchDB的默認端口是5984,用戶可以使用link指令進行容器鏈接:

$ docker run --name couchdb-app --link couchdb-container:couch couchdb

獲取容器IP之后,用戶可以使用curl指令,通過CouchDB API來操作CouchDB容器:

$ curl http://192.168.99.100:5984

{"couchdb":"Welcome","uuid":"7298b57db384b931f43bbc8c49e75b53","version":"1.6.1",

"vendor":{"name":"The Apache Software Foundation","version":"1.6.1"}}

Cassandra

Cassandra是個開源(Apache License 2.0)的分布式數據庫,支持分散的數據存儲,可以實現容錯以及無單點故障等。Cassandra在設計上引入了P2P技術,具備大規模可分區行存儲能力,並支持Spark、Storm、Hadoop的集成。目前Facebook、Twitter、Instagram、eBay、Github、Reddit、Netflix等多家公司都在使用Cassandra。類似工具還有HBase等。

1.使用官方鏡像

首先可以使用docker run指令基於Cassandra官方鏡像啟動容器:

$ docker run --name my-cassandra -d cassandra:latest

1dde81cddc53322817f8c6e67022c501759d8d187a2de40f1a25710a5f2dfa53

這里的--name標簽指定容器名稱。cassandra:tag中的標簽指定版本號。

標簽名稱可以參考官方倉庫的標簽說明:https://hub.docker.com/r/library/cassandra/tags/

用戶可以將另一個容器中的應用與Cassandra容器連接起來。此應用容器要暴露Cassandra需要使用的端口(Cassandra默認服務端口為rpc_port:9160;CQL默認本地服務端口為native_transport_port:9042),這樣就可以通過容器link功能來連接Cassandra容器與應用容器:

$ docker run --name my-app --link my-cassandra:cassandra -d app-that-uses-cassandra

2.搭建Cassandra集群

Cassandra有兩種集群模式:單機模式(所有實例集中於一台機器)和多機模式(實例分布於多台機器)。

單機模式下,可以按照上面描述的方法啟動容器即可。

如果需要啟動更多實例,則需要在指令中配置首個實例信息:

$ docker run --name my-cassandra2 -d -e CASSANDRA_SEEDS="$(docker inspect --format='{{ .NetworkSettings.IPAddress }}' my-cassandra)" cassandra:latest

其中my-cassandra就是首個Cassandra Server的實例名稱。在這里使用了docker inspect指令,以獲取首個實例的IP地址信息。

還可以使用docker run的--link標簽來連接這兩個Cassandra實例:

$ docker run --name my-cassandra2 -d --link my-cassandra:cassandra cassandra:latest

多機模式下,由於容器網絡基於Docker bridge,所以需要通過環境變量配置Cassandra Server容器的IP廣播地址(即使用-e標簽)

假設第一台虛擬機的IP是10.22.22.22,第二台虛擬機的IP是10.23.23.23,Gossip端口是7000。

那么啟動第一台虛擬機中的Cassandra容器時的指令如下:

$ docker run --name my-cassandra -d -e CASSANDRA_BROADCAST_ADDRESS=10.42.42.42 -p 7000:7000 cassandra:latest

啟動第二台虛擬機的Cassandra容器時,同樣需要暴露Gossip端口,並通過環境變量聲明第一台Cassandra容器的IP地址:

$ docker run --name my-cassandra -d -e CASSANDRA_BROADCAST_ADDRESS=10.43.43.43 -p 7000:7000 -e CASSANDRA_SEEDS=10.42.42.42 cassandra:latest

小結

在使用數據庫容器時,建議將數據庫文件映射到宿主主機,一方面減少容器文件系統帶來的性能損耗,另一方面實現數據的持久化。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM