NoSQL從小白到碼神 火推08

NoSQL從小白到碼神

本課程適用於運維、開發相關人員。

課程目錄:html

- NoSQL背景
- NoSQL簡介
- NoSQL和關係型數據庫對比

- Redis簡介
- Redis下載安裝配置(Linux環境)
- Redis優勢
- Redis性能
- Redis常見命令
- Redis數據類型
- Redis的功能
    - Redis發佈/訂閱
    - Redis事務支持
    - Redis主從複製(集羣)
    - Redis持久化
- Java操做Redis示例
- Redis總結

- MongoDB簡介
- MongoDB下載安裝(Linux)
- MongoDB基本操做
    - 體系結構
    - 啓動、中止數據庫
    - 鏈接數據庫
    - 增刪改查操做
    - 高級查詢操做
    - 數據備份、恢復
    - 訪問控制
    - 索引
    - Replica Sets
    - 自動分片(Auto-Sharding)
- MongoDB常見命令
- MongoDB工具集
- MongoDB集羣搭建
- MongoDB安全驗證
- MongoDB應用場景
- Java操做MongoDB示例
- MongoDB總結

NoSQL篇

 

NoSQL背景

隨着互聯網Web網站的興起,傳統的關係數據庫在應付Web網站,特別是超大規模和高併發的社交網絡類型的Web純動態網站已經顯得力不從心,暴露出了不少難以克服的問題。例如:關係數據庫爲了下降數據冗餘,保證數據約束性,在數據查詢時不得不使用多個數據表之間的鏈接操做,這極大地下降了查詢效率,不可以知足當前Internet的高實時性的要求。而非關係型數據庫對併發的大規模訪問有着效率上的優點,所以,非關係數據庫是在具體應用背景下獲得了迅速的發展。java

NoSQL簡介

NoSQL指的是非關係型的數據庫。其實,NoSQL概念最先出如今1998年,當時的含義是反SQL技術革命運動,但並未引發太多的關注。直到2009年,NoSQL概念被來自Rackspace的EricEvans再次提出,這時的NoSQL已經不是單純的反SQL運動,指的主要是非關係型的分佈式數據庫,而且不支持原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)的數據庫設計模式。在亞特蘭大舉行的有關NoSQL的討論會上,學者給出了NoSQL較爲廣泛的解釋,即「非關係型的」。而且指出Key-Value存儲和文檔數據庫是NoSQL的主要特色。linux

  • 原子性:redis

    多個事情組成一個單元,要麼同時成功或失敗,不能只運行其中一個算法

  • 一致性:sql

    事務處理要將數據庫從一種狀態轉變爲另外一種狀態。一旦提交了修改數據,那麼其它人讀取這個數據,也是被修改後的數據mongodb

  • 隔離性:數據庫

    在事務處理提交以前,事務處理的效果不能由系統中其它事務處理。多個用戶,不能同時讀寫同一個數據,應該有前後順序,在數據庫中是一個一 個事件地運行,若是事件的條件不知足,後續事件就回滾json

  • 持久性:vim

    事件一旦提交成功,數據就發生了變化

例如:

網上定p系統,扣錢和定p是一個事務,它須要有原子性即不能只運行扣錢不運行定p。符合原子性。

這張p被多人同時在網上定,就會有先來的才定上這個p,後來定p的動做,若是發現p已賣出,(p的狀態改變了,其它人經過網站訪問這個數據,就會發現p已賣出符合一致性),就會回滾到不扣錢,p訂不上的狀態。符合隔離性。

p被定了,在數據庫裏設置標誌位,它就一直顯示爲賣出狀態。符合持久性

NoSQL特色

1:key-value存儲

2:最終一致性

3:可拓展

NoSQL和關係型數據庫對比

關係型數據庫

優點:
    1.擅長小數據量的處理
    2.擅長複雜的SQL操做,能夠進行Join等複雜查詢
    3.能夠方便的生成各類數據對象,利用存儲的數據創建窗體和報表,可視性好

劣勢:
    1.很難進行分佈式應用和大量數據的寫入處理
    2.爲有數據更新的表作索引和結構變動
    3.字段不固定的應用
    4.對簡單查詢須要快速返回結果的處理

NoSQL數據庫

優點:
    1.擅長大量數據的寫入和讀取
    2.快速的查詢響應,靈活的數據模型
    3.數據結構變動或更新很是方便,不須要更改已有數據的數據結構
    4.擊碎了性能瓶頸,可使執行速度變的更快

劣勢:
    1.不提供複雜的API接口
    2.通常僅提供key索引
    3.不適合小數據的處理
    4.現有產品的不夠成熟,大多數產品都還處於初創期

NoSQL 數據庫分類

Redis篇

 

Redis簡介

Redis(REmote DIctionary Server)是一個開源的使用ANSI C語言編寫、是一個由Salvatore Sanfilippo寫的key-value存儲系統,支持網絡、可基於內存亦可持久化的日誌型、並提供多種語言的API。

Redis是一個key-value存儲系統。和Memcached相似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。與memcached同樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步。

(Memcached 是一個高性能的分佈式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它經過在內存中緩存數據和對象來減小讀取數據庫的次數,從而提升動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。)

 

參考地址:http://www.runoob.com/redis/redis-conf.html

Redis下載安裝配置(Linux環境)

下載:

官網:https://redis.io/

下載步驟:

安裝(Linux版本下CentOS Linux release 7.3.1611 (Core))

在線安裝:

1:查看系統版本:

cat /etc/redhat-release

2:進入到opt目錄下、建立redis文件夾:

cd /opt/
mkdir redis

3:進入/opt/redis/目錄下,下載redis

wget http://download.redis.io/releases/redis-4.0.6.tar.gz

若是wget 未安裝, 顯示 未找到命令

須要到根目錄下  

cd /

yum install wget -y

等待安裝完成便可重複第3步

 

4:解壓redis-4.0.6.tar.gz

tar -zvxf redis-4.0.6.tar.gz

5:在安裝以前須要預裝gcc、tcl

沒有安裝的小夥伴,須要安裝,若是已經存在,則略過此步驟

回到根目錄 cd/
查看安裝gcc信息:
gcc -v
安裝命令:
mount /dev/cdrom /mnt
yum install gcc tcl -y

6:執行redis安裝

make
或者 make MALLOC=libc

7:切換到目錄/usr下新建目錄/usr/lksoft/redis

cd /usr
mkdir lksoft
cd lksoft
mkdir redis

8:從新設置PREFIX

切換到目錄  cd /opt/redis/redis-4.0.6

make PREFIX=/usr/lksoft/redis/ install

9:查看當前系統中端口使用狀況

ss -tanl

10:將redis設置成服務(配置環境變量)

cd ./opt/redis/redis-4.0.6/src
cp redis-sentinel /usr/lksoft/redis/bin/

11:設置環境變量bash_profile

切換到根目錄 cd / 

vim ~/.bash_profile 或者 vi ~/.bash_profile

修改內容部分:

export REDIS_HOME=/usr/lksoft/redis
export PATH=$PATH:$REDIS_HOME/bin

使文件生效
source ~/.bash_profile

12:任何地方,均可以啓動redis了

爲了更說明,切換到根目錄下
cd /
能夠自動補全redis-server了

13:將redis啓動程序作成服務

切換到以前的redis目錄:
cd /opt/redis/redis-4.0.6/utils

./install_server.sh 

提示是否使用默認的6379端口,點擊回車便可,使用默認
Please select the redis port for this instance: [6379] 

是否將redis的服務配置文件,放到[/etc/redis/6379.conf]下面,直接回車便可:
Please select the redis config file name [/etc/redis/6379.conf] 

是否將redis服務的日誌文件,放到[/var/log/redis_6379.log]下面,直接回車便可:
Please select the redis log file name [/var/log/redis_6379.log]

是否將redis的數據,存放到[/var/lib/redis/6379]下面,直接回車便可:
Please select the data directory for this instance [/var/lib/redis/6379]

是否默認redis可執行的文件路徑爲[/usr/lksoft/redis/bin/redis-server],直接回車便可
Please select the redis executable path [/usr/lksoft/redis/bin/redis-server] 

而後顯示的是設置的文件信息,直接回車便可。

發現:Copied /tmp/6379.conf => /etc/init.d/redis_6379

14:修改啓動的名稱

cd /etc/init.d/
mv redis_6379 redisd

15:啓動redis

service redisd start
發現已經啓動
須要中止服務:
service redisd stop
從新啓動
service redisd start
查看目前系統使用端口狀況:
ss -tanl

16:測試鏈接redis

切換到根目錄
cd /

查看客戶端鏈接幫助
redis-cli --help

鏈接0號庫
redis-cli

 

config get * 查看配置信息

 

Redis優勢

  • 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
  • 豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操做。
  • 原子 – Redis的全部操做都是原子性的,意思就是要麼成功執行要麼失敗徹底不執行。單個操做是原子性的。多個操做也支持事務,即原子性,經過MULTI和EXEC指令包起來。
  • 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過時等等特性。
  • Redis支持數據的持久化,能夠將內存中的數據保存在磁盤中,重啓的時候能夠再次加載進行使用。
  • Redis支持數據的備份,即master-slave模式的數據備份。

Redis性能

在50個併發的狀況下請求10W次,寫的速度是11W次/s,讀的速度是8.1w次/s

Redis常見命令

官網參考命令地址:https://redis.io/commands

菜鳥教程命令地址:http://www.runoob.com/redis

對value操做的命令

exists(key):確認一個key是否存在
del(key):刪除一個key
type(key):返回值的類型
keys(pattern):返回知足給定pattern的全部key
randomkey:隨機返回key空間的一個
keyrename(oldname, newname):重命名key
dbsize:返回當前數據庫中key的數目
expire:設定一個key的活動時間(s)
ttl:得到一個key的活動時間
select(index):按索引查詢
move(key, dbindex):移動當前數據庫中的key到dbindex數據庫
flushdb:刪除當前選擇數據庫中的全部key
flushall:刪除全部數據庫中的全部key

對string操做的命令

set(key, value):給數據庫中名稱爲key的string賦予值value
get(key):返回數據庫中名稱爲key的string的value
getset(key, value):給名稱爲key的string賦予上一次的value
mget(key1, key2,…, key N):返回庫中多個string的value
setnx(key, value):添加string,名稱爲key,值爲value
setex(key, time, value):向庫中添加string,設定過時時間time
mset(key N, value N):批量設置多個string的值
msetnx(key N, value N):若是全部名稱爲key i的string都不存在
incr(key):名稱爲key的string增1操做
incrby(key, integer):名稱爲key的string增長integer
decr(key):名稱爲key的string減1操做
decrby(key, integer):名稱爲key的string減小integer
append(key, value):名稱爲key的string的值附加value
substr(key, start, end):返回名稱爲key的string的value的子串

對List 操做的命令

rpush(key, value):在名稱爲key的list尾添加一個值爲value的元素
lpush(key, value):在名稱爲key的list頭添加一個值爲value的 元素
llen(key):返回名稱爲key的list的長度
lrange(key, start, end):返回名稱爲key的list中start至end之間的元素
ltrim(key, start, end):截取名稱爲key的list
lindex(key, index):返回名稱爲key的list中index位置的元素
lset(key, index, value):給名稱爲key的list中index位置的元素賦值
lrem(key, count, value):刪除count個key的list中值爲value的元素
lpop(key):返回並刪除名稱爲key的list中的首元素
rpop(key):返回並刪除名稱爲key的list中的尾元素
blpop(key1, key2,… key N, timeout):lpop命令的block版本。
brpop(key1, key2,… key N, timeout):rpop的block版本。
rpoplpush(srckey, dstkey):返回並刪除名稱爲srckey的list的尾元素,並將該元素添加到名稱爲dstkey的list的頭部

對Set操做的命令

sadd(key, member):向名稱爲key的set中添加元素member
srem(key, member) :刪除名稱爲key的set中的元素member
spop(key) :隨機返回並刪除名稱爲key的set中一個元素
smove(srckey, dstkey, member) :移到集合元素
scard(key) :返回名稱爲key的set的基數
sismember(key, member) :member是不是名稱爲key的set的元素
sinter(key1, key2,…key N) :求交集
sinterstore(dstkey, (keys)) :求交集並將交集保存到dstkey的集合
sunion(key1, (keys)) :求並集
sunionstore(dstkey, (keys)) :求並集並將並集保存到dstkey的集合
sdiff(key1, (keys)) :求差集
sdiffstore(dstkey, (keys)) :求差集並將差集保存到dstkey的集合
smembers(key) :返回名稱爲key的set的全部元素
srandmember(key) :隨機返回名稱爲key的set的一個元素

對Hash操做的命令

hset(key, field, value):向名稱爲key的hash中添加元素field
hget(key, field):返回名稱爲key的hash中field對應的value
hmget(key, (fields)):返回名稱爲key的hash中field i對應的value
hmset(key, (fields)):向名稱爲key的hash中添加元素field 
hincrby(key, field, integer):將名稱爲key的hash中field的value增長integer
hexists(key, field):名稱爲key的hash中是否存在鍵爲field的域
hdel(key, field):刪除名稱爲key的hash中鍵爲field的域
hlen(key):返回名稱爲key的hash中元素個數
hkeys(key):返回名稱爲key的hash中全部鍵
hvals(key):返回名稱爲key的hash中全部鍵對應的value
hgetall(key):返回名稱爲key的hash中全部的鍵(field)及其對應的value

Redis數據類型

  • string(字符串)

    • string是redis最基本的類型,並且string類型是二進制安全的。意思是redis的string能夠包含任何數據。好比jpg圖片或者序列化的對象
    • 從內部實現來看其實string能夠看做byte數組,最大上限是1G字節
    • string類型的值也可視爲integer,從而可讓「incr」命令族操做,這種狀況下,該integer的值限制在64位有符號數
    • 在list、set和zset中包含的獨立的元素類型都是string類型

    應用場景:String是最經常使用的一種數據類型,普通的key/value存儲.

  • list(雙向鏈表)

    • redis的list類型其實就是一個每一個子元素都是string類型的雙向鏈表,因此[lr]push和[lr]pop命令的算法時間複雜度都是O(1),另外list會記錄鏈表的長度,因此llen操做也是O(1).
    • 能夠經過push,pop操做從鏈表的頭部或者尾部添加刪除元素。這使得list既能夠用做棧,也能夠用做隊列
    • list的最大長度是2^32-1個元素

    應用場景:Redis list應用場景很是多,也是Redis最重要的數據結構之一,好比twitter的關注列表,粉絲列表等均可以用Redis的list結構來實現.

  • set(無序集合)

    • set就是redis string的無序集合,不容許有重複元素
    • set的最大元素數是2^32-1
    • 對set的操做還有交集、並集、差集等

    應用場景:Set對外提供的功能與list相似,當你須要存儲一個列表數據,又不但願出現重複數據時,set 是一個很好的選擇,而且set提供了判斷某個成員是否在一個set集合內的接口,這個也是list所不能提供的

  • Sorted set(有序集合)-- zset

    • zset是set的一個升級版本,在set的基礎上增長了一個順序屬性,這一屬性在添加修改元素時能夠指定,每次指定後zset會自動安裝指定值從新調整順序。能夠理解爲一張表,一列存value,一列存順序。操做中的key理解爲zset的名字。
    • zset的最大元素數是2^32-1。
    • 對於已經有序的zset,仍然可使用sort命令,經過指定asc|desc參數對其進行排序。

    應用場景:Sorted set的使用場景與set相似,區別是set不是自動有序的,而sorted set能夠經過用戶額外提供一個優先級(score)的參數來爲成員排序,而且是插入有序的,即自動排序.當你須要一個有序的而且不重複的集合列表,那麼能夠選擇sorted set數據結構

  • hash(hash表)

    • redis Hash類型對數據域和值提供了映射,這一結構很方便表示對象
    • 在Hash中能夠只保存有限的幾個「域」,而不是將全部的「域」做爲key,這能夠節省內存

    應用場景:好比,咱們存儲供應商酒店價格的時候能夠採起此結構,用酒店編碼做爲Key, 價格信息做爲Value

Redis的功能

  • Redis發佈/訂閱

    Redis的發佈/訂閱(Publish/Subscribe)功能相似於傳統的消息路由功能,發佈者發佈消息,訂閱者接收消息,溝通發佈者和訂閱者之間的橋樑是訂閱的Channel或者Pattern.訂閱者和發佈者之間的關係是鬆耦合的,發佈者不指定哪一個訂閱者才能接收消息,訂閱者不僅接收特定發佈者的消息.

  • Redis事務支持

    Redis目前對事務支持還比較簡單,也即支持一些簡單的組合型的命令,只能保證一個client發起的事務中的命令能夠連續的執行,而中間不會插入其餘client的命令. 因爲Redis是單線程來處理全部client的請求的因此作到這點是很容易的.事務的執行過程當中,若是redis意外的掛了,這時候事務可能只被執行了一半,能夠用redis-check-aof 工具進行修復

  • Redis主從複製(集羣)

    Master/Slave配置:
    
    Master IP:175.41.209.118
    
    Master Redis Server Port:6379
    
    Slave配置很簡單,只須要在slave服務器的redis.conf加入:
    
    slaveof 175.41.209.118 6379
    
    啓動master和slave,而後寫入數據到master,讀取slave,能夠看到數據被複制到slave了.
    
    
    用途:讀寫分離,數據備份,災難恢復等

    Redis主從複製過程:

    配置好slave後,slave與master創建鏈接,而後發送sync命令. 
    
    不管是第一次鏈接仍是從新鏈接,master都會啓動一個後臺進程,將數據庫快照保存到文件中,同時master主進程會開始收集新的寫命令並緩存. 
    
    後臺進程完成寫文件後,master就發送文件給slave,slave將文件保存到硬盤上,再加載到內存中。
    
    接着master就會把緩存的命令轉發給slave,後續master將收到的寫命令發送給slave. 
    
    若是master同時收到多個slave發來的同步鏈接命令,master只會啓動一個進程來寫數據庫鏡像, 而後發送給全部的slave

    Redis主從複製特色:

    1. master能夠擁有多個slave.
    2. 多個slave能夠鏈接同一個master外,還能夠鏈接到其餘slave.
    3. 主從複製不會阻塞master,在同步數據時,master能夠繼續處理client請求.
    4. 能夠在master禁用數據持久化,註釋掉master配置文件中的全部save配置,只需在slave上配置數據持久化.
    5. 提升系統的伸縮性

    Redis主從複製速度:

    官方提供了一個數據, 㻿lave在21秒即完成了對Amazon網站 10G key set的複製.
  • Redis持久化

    因爲Redis是內存數據庫,它將本身的數據庫狀態存儲在內存裏面,因此若是不想辦法將儲存在內存中的數據庫狀態保存到磁盤裏面,那麼一旦服務器退出,服務器中的數據庫狀態也會消失不見。爲了解決這個問題,Redis提供了RDB、AOF持久化方式,將內存中的數據保存到磁盤中,避免數據意外丟失

    (1)RDB是 Snapshotting(快照)也是默認方式: 快照是默認的持久化方式。這種方式將內存中數據以快照的方式寫入到二進制文件中,默認的文件名爲dump.rdb。能夠配置自動作快照持久 化的方式。咱們能夠配置redis在n秒內若是超過m個key被修改就自動作快照

    RDB持久化經過將服務器某個時間點上的數據庫狀態(非空數據庫以及相關鍵值對)保存到一個RDB文件中,Redis服務器能夠用它來還原數據庫狀態。 SAVE命令會阻塞Redis服務器進程。而BGSAVE會派生出一個子進程,而後由子進程負責建立RDB文件,服務器父進程繼續處理命令請求。還能夠SAVE命令設置自動間隔保存, 例如SAVE 60 10000 服務器在60秒以內,對數據庫進行了至少10000次修改,自動執行BGSAVE命令。RDB文件是一個通過壓縮的二進制文件。

    (2)AOF(Append-only file): AOF持久化經過保存Redis服務器所執行的寫命令來記錄數據庫狀態的。被寫入AOF文件的全部命令都是以Redis的命令請求協議格式保存的,Redis的命令請求協議保存爲純文本格式。AOF持久化功能的實現分爲命令追加、文件寫入、文件同步三個步驟:當AOF持久化處於打開狀態時,服務器在執行完一個寫命令後,會以協議格式將被執行的寫命令(如SET、SADD、RPUSH)追加到服務器狀態的aofbuf緩衝區的末尾。服務器在每次結束一個事件循環以前,它都會調用flushAppendOnlyFile函數,考慮是否須要將aof_buf緩衝區中的內容寫入和保存到AOF文件裏面。flushAppendOnlyFile函數的行爲由服務器配置的appendfsync選項的值( always 、 everysec(默認) 、 no )來決定

    RDB與AOF比較

    RDB 
    優勢:RDB 是一個很是緊湊的文件,它保存了 Redis 在某個時間點上的數據集。這種文件很是適合用於進行備份。

    缺點:若是你須要儘可能避免在服務器故障時丟失數據,那麼 RDB 不適合你。 雖然 Redis 容許你設置不一樣的保存點(save point)來控制保存 RDB 文件的頻率, 可是, 由於RDB 文件須要保存整個數據集的狀態,因此它並非一個輕鬆的操做。所以你可能會至少 5 分鐘才保存一次 RDB 文件。 在這種狀況下, 一旦發生故障停機, 你就可能會丟失好幾分鐘的數據。

    AOF 
    優勢:使用 AOF 持久化會讓 Redis 變得很是耐久:你能夠設置不一樣的 fsync 策略,好比無 fsync ,每秒鐘一次 fsync ,或者每次執行寫入命令時 fsync 。 AOF 的默認策略爲每秒鐘 fsync 一次,在這種配置下,Redis 仍然能夠保持良好的性能,而且就算髮生故障停機,也最多隻會丟失一秒鐘的數據( fsync 會在後臺線程執行,因此主線程能夠繼續努力地處理命令請求)。

    缺點:對於相同的數據集來講,AOF 文件的體積一般要大於 RDB 文件的體積。根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB 。

Java操做Redis示例

所需jar包:

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

java操做:

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import redis.clients.jedis.Jedis;

public class RedisTest {

    public static void main(String[] args) {
//獲取redis的鏈接
		//表明使用端口號爲6379,默認,若是端口號非默認的,則須要new Jedis("192.168.168.226",8888);
		
        Jedis jd = new Jedis("39.106.131.203");
        System.out.println("鏈接redis成功");
//須要設置redis服務器(虛擬機中的6379.conf文件,將bind修改成:0.0.0.0)
    //  System.out.println("服務正在運行" + jd.ping());

        /**
         * 操做string類型
         */

    //  jd.set("key2", "java1212");
    //  System.out.println("redis中存儲的值爲:"+jd.get("key2"));

        /**
         * 操做list類型
         */

    //  jd.lpush("list", "listvalue1");
    //  jd.lpush("list", "listvalue2");
    //  jd.lpush("list", "listvalue3");
    //      
    //  List<String> list = jd.lrange("list", 0, 2);
    //  for (int i = 0; i < list.size(); i++) {
    //      System.out.println("list的結果是:" + list.get(i));
    //  }

        /**
         * 操做set類型
         */

        jd.sadd("setKey1", "setvalue1");
        jd.sadd("setKey1", "setvalue2");
        jd.sadd("setKey1", "setvalue3");
        Set<String> keys = jd.keys("*");
    //  Set<String> keys = jd.smembers("setKey1");
        Iterator<String> it = keys.iterator();
        while(it.hasNext()){
            String key = it.next();
            System.out.println(key);
        }
    }
}

Redis總結

Redis使用最佳方式是所有數據in-memory。 
Redis更多場景是做爲Memcached的替代者來使用。 
當須要除key/value以外的更多數據類型支持時,使用Redis更合適。 
當存儲的數據不能被剔除時,使用Redis更合適。(持久化)

MongoDB篇

 

MongoDB簡介

  • MongoDB是一個跨平臺,面向文檔的數據庫,提供高性能,高可用性和易於擴展。MongoDB是工做在集合和文檔上一種概念
  • MongoDB 是一個基於分佈式文件存儲的數據庫。由C++語言編寫。旨在爲WEB應用提供可擴展的高性能數據存儲解決方案
  • MongoDB 是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。他支持的數據結構很是鬆散,是相似json的bson格式,所以能夠存儲比較複雜的數據類型。Mongo最大的特色是他支持的查詢語言很是強大,其語法有點相似於面向對象的查詢語言,幾乎能夠實現相似關係數據庫單表查詢的絕大部分功能,並且還支持對數據創建索引

MongoDB特色

  • 面向集合存儲,易於存儲對象類型的數據
  • 模式自由
  • 支持動態查詢
  • 支持徹底索引,包含內部對象
  • 支持查詢
  • 支持複製和故障恢復
  • 使用高效的二進制數據存儲,包括大型對象(如視頻等)
  • 自動處理碎片,以支持雲計算層次的擴展性
  • 支持 Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及 C++語言的驅動程序
  • 文件存儲格式爲 BSON(一種 JSON 的擴展),文檔型
  • 可經過網絡訪問

面向集合(Collenction-Orented)

  • 意思是數據被分組存儲在數據集中,被稱爲一個集合(Collenction)。每一個集合在數據庫中都有一個惟一的標識名,而且能夠包含無限數目的文檔。集合的概念相似關係型數據庫(RDBMS)裏的表(table),不一樣的是它不須要定義任何模式(schema)

模式自由(schema-free)

  • 意味着對於存儲在 MongoDB 數據庫中的文件,咱們不須要知道它的任何結構定義。提了這麼屢次"無模式"或"模式自由",它到是個什麼概念呢? 例如,下面兩個記錄能夠存在於同一個集合裏面:

    {"welcome" : "Beijing"}

    {"age" : 25}

文檔型:

  • 意思是咱們存儲的數據是鍵-值對的集合,鍵是字符串,值能夠是數據類型集合裏的任意類型,包括數組和文檔. 咱們把這個數據格式稱做 「BSON」 即 「Binary Serialized dOcument Notation.」

MongoDB應用場景

適合場景:

1.網站數據,實時的插入,更新與查詢。
2.因爲性能很高,可作持久化緩存層。
3.存儲大尺寸,低價值的數據。
4.高伸縮性的集羣場景。
5.BSON格式很是適合文檔化數據的存儲及查詢。

不適合場景:

1.高度事務性的系統,例如銀行或會計系統。
2.傳統的商業智能應用,針對特定問題的BI數據庫會對產生高度優化的查詢方式。對於此類應用,數據倉庫多是更合適的選擇。

MongoDB下載安裝(Linux)

教程系統版本:(Linux版本下CentOS Linux release 7.3.1611 (Core))

下載:

1:在線下載

    wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.9.tgz

2:官網下載

    https://www.mongodb.com/download-center?ct=atlasheader#atlas

安裝(在線安裝):

1:進入/opt目錄下

cd /opt

2:建立文件夾

mkdir mongodb

3:進入mongodb目錄下,在線下載mongodb資源安裝包

cd mongodb/
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.9.tgz

4:解壓mongodb資源包到當前路徑下

tar -zvxf mongodb-linux-x86_64-3.2.9.tgz

5:進入目錄/usr/local/下,並建立文件夾mongodb

cd /usr/local
mkdir mongodb

6:將mongodb-linux-x86_64-3.2.9文件夾內的內容 移動到 /usr/local/mongodb下

mv /opt/mongodb/mongodb-linux-x86_64-3.2.9/*  /usr/local/mongodb

7:在mongodb目錄下,新建1個文件夾和1個文件

mkdir data
touch logs

8:在系統執行文件~/.bash_profile中添加mongodb的執行命令

vim ~/.bash_profile
內容爲:
    PATH=$PATH:$HOME/bin:/usr/local/mongodb/bin

source ~/.bash_profie

注意:

export MONGODB_HOME=/usr/local/mongodb    //配置剛纔的路徑

PATH=$PATH:$HOME/bin:/usr/local/mongodb/bin

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export REDIS_HOME=/usr/lksoft/redis
export MONGODB_HOME=/usr/local/mongodb

PATH=$PATH:$HOME/bin:/usr/local/mongodb/bin
export PATH

Mongodb啓動方式

mongodb有三種啓動方式:

啓動1:進入/bin目錄下,輸入mongod --dbpath=/usr/local/mongodb/data --fork --logpath=/usr/local/mongodb/logs  

    啓動以後,輸入mongo就能夠進入mongodb客戶端鏈接
    而後輸入show dbs;若是顯示數據庫,則啓動搭建成功

啓動2:配置啓動文件啓動mongodb.conf(推薦)

    mongodb.conf內容:

    logpath=/usr/local/mongodb/logs
    logappend = true 
    #fork and run in background
    fork = true
    #port = 27017
    dbpath=/usr/local/mongodb/data
    #location of pidfile
    pidfilepath=/usr/local/mongodb/mongod.pid 

以前打開數據庫了,因此先關庫:
可使用db.shutdownServer()命令,或者ps -ef|grep mongod查看進程號,使用kill -9 進程號便可

mongod --config /usr/local/mongodb/mongodb.conf 啓動

啓動3:配置service服務啓動(推薦)

MongoDB基本操做

  • 體系結構

MongoDB 是一個可移植的數據庫,它在流行的每個平臺上均可以使用,即所謂的跨平臺 特性。在不一樣的操做系統上雖然略有差異,可是從總體構架上來看,MongoDB 在不一樣的平 臺上是同樣的,如數據邏輯結構和數據的存儲等等。

一個運行着的 MongoDB 數據庫就能夠當作是一個 MongoDB Server,該 Server 由實例和數據庫組成,在通常的狀況下一個 MongoDB Server 機器上包含一個實例和多個與之對應的數據庫,可是在特殊狀況下,如硬件投入成本有限或特殊的應用需求,也容許一個 Server 機器上能夠有多個實例和多個數據庫。

MongoDB 中一系列物理文件(數據文件,日誌文件等)的集合或與之對應的邏輯結構(集 合,文檔等)被稱爲數據庫,簡單的說,就是數據庫是由一系列與磁盤有關係的物理文件的 組成。

-  數據邏輯結構
     MongoDB 的邏輯結構是一種層次結構。主要由:文檔(document)、集合(collection)、數據庫(database)這三部分組成的。邏輯結構是面向用戶的,用戶使用 MongoDB 開發應用程序使用的就是邏輯結構。
        1: MongoDB 的文檔(document),至關於關係數據庫中的一行記錄
        2:多個文檔組成一個集合(collection),至關於關係數據庫的表
        3:多個集合(collection),邏輯上組織在一塊兒,就是數據庫(database)
        4:一個 MongoDB 實例支持多個數據庫(database)
- 數據存儲結構
    MongoDB 的默認數據目錄是/data/db,它負責存儲全部的 MongoDB 的數據文件。在 MongoDB內部,每一個數據庫都包含一個.ns 文件和一些數據文件,並且這些數據文件會隨着數據量的增長而變得愈來愈多

對比:

  • 啓動、中止數據庫

    參考上面啓動方式
  • 鏈接數據庫

    參考上面鏈接命令

  • mongod參數說明

    mongod 的主要參數有:
     dbpath:
        數據文件存放路徑,每一個數據庫會在其中建立一個子目錄,用於防止同一個實例屢次運行的 mongod.lock 也保存在此目錄中。
    logpath
        錯誤日誌文件
    logappend
        錯誤日誌採用追加模式(默認是覆寫模式)
    bind_ip
        對外服務的綁定 ip,通常設置爲空,及綁定在本機全部可用 ip 上,若有須要能夠單獨指定
    port
        對外服務端口。Web 管理端口在這個 port 的基礎上+1000 
    fork
        之後臺 Daemon 形式運行服務
    journal
        開啓日誌功能,經過保存操做日誌來下降單機故障的恢復時間,在 1.8 版本後正式加入,取代在 1.7.5 版本中的 dur 參數。
    syncdelay
        系統同步刷新磁盤的時間,單位爲秒,默認是 60 秒。
    directoryperdb
        每一個 db 存放在單獨的目錄中,建議設置該參數。與 MySQL 的獨立表空間相似maxConns最大鏈接數
    repairpath
        執行 repair 時的臨時目錄。在若是沒有開啓 journal,異常 down 機後重啓,必須執行 repair
    操做

常見命令

show dbs:顯示數據庫列表 
show collections:顯示當前數據庫中的集合(相似關係數據庫中的表) 
show users:顯示用戶
use <db name>:切換當前數據庫,這和MS-SQL裏面的意思同樣 
db.help():顯示數據庫操做命令,裏面有不少的命令 
db.foo.help():顯示集合操做命令,一樣有不少的命令,foo指的是當前數據庫下,一個叫foo的集合,並不是真正意義上的命令 
db.foo.find():對於當前數據庫中的foo集合進行數據查找(因爲沒有條件,會列出全部數據) 
db.foo.find( { a : 1 } ):對於當前數據庫中的foo集合進行查找,條件是數據中有一個屬性叫a,且a的值爲1
MongoDB沒有建立數據庫的命令,但有相似的命令。
修復當前數據庫   db.repairDatabase();
查看當前使用的數據庫  
    db.getName();
     db; db和getName方法是同樣的效果,均可以查詢當前使用的數據庫
顯示當前db狀態  db.stats();
當前db版本  db.version();
查看當前db的連接機器地址  db.getMongo();

基本操做

  • 添加文檔:

    db.users.insert({ 
        「_id」:ObjectId("52c3c518498a9646a48133a2"),
        「name」:「likang」, 
        「email」:「likang@qq.com」
    }); 
    db.users.save({ 
        「_id」:ObjectId("52c3c518498a9646a48133a2"),
        「name」:「likang2」, 
        「email」:「likang2@qq.com」
    }); 
    
    insert 當_id存在時報錯
    save 當_id存在時覆蓋更新
  • 刪除文檔:

    //刪除所有
    db.user.remove(); 
    //刪除指定記錄
    db.user.remove({「name」:「likang」}); 
    
    //刪除user集合
    db.user.drop();

更新文檔:

原⽂檔:
    { 
        「_id」:ObjectId("52c3c518498a9646a48133a2"),
        「name」:「likang」, 
        「email」:「likang@qq.com」
    } 
    !
    修改後的⽂檔:
    { 
        「_id」:ObjectId("52c3c518498a9646a48133a2"),
        「name」:「likang」, 
        「email」:[
            「likang@qq.com」, 
            「likang2@qq.com」 
        ] 
    }

    var doc = db.users.findOne({"name" : 「likang」});
    doc.email =[ 
        「likang@qq.com」, 
        「likang2@qq.com」 
    ]; 
    db.users.update({ "name" : "likang" }, doc);

    // 更新:指定第三個參數爲true能夠開啓upsert模式
    //根據條件查找不到數據則建立⼀條新的
    db.users.update({ "name" : "likang" }, doc, true);
  • 查詢文檔:

經常使用工具集

MongoDB 在 bin 目錄下提供了一系列有用的工具,這些工具提供了 MongoDB 在運維管理上的方便。

  • bsondump: 將 bson 格式的文件轉儲爲 json 格式的數據
  • mongo: 客戶端命令行工具,其實也是一個 js 解釋器,支持 js 語法
  • mongod: 數據庫服務端,每一個實例啓動一個進程,能夠 fork 爲後臺運行
  • mongodump/ mongorestore: 數據庫備份和恢復工具
  • mongoexport/ mongoimport: 數據導出和導入工具
  • mongofiles: GridFS 管理工具,可實現二制文件的存取 -mongos: 分片路由,若是使用了 sharding 功能,則應用程序鏈接的是 mongos 而不是 mongod
  • mongosniff: 這一工具的做用相似於 tcpdump,不一樣的是他只監控 MongoDB 相關的包請求,而且是以指定的可讀性的形式輸出
  • mongostat: 實時性能監控工具

Java操做MongoDB示例

  • 新建maven project工程

  • 配置所需jar包

    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
        <version>3.3.0</version>
    </dependency>
  • 增長鏈接mongodb的工具類

    /**
     * mongodb工具類
     * @author likang
     * @date   2017-4-23 下午8:19:53
     */
    public class MongoDbUtil {
    
        private static MongoCollection<Document> collection;
    
        /**
         * 連接數據庫
         * 
         * @param databaseName 數據庫名稱
         * @param collectionName 集合名稱
         * @param hostName 主機名
         * @param port  端口號
         */
        public static void connect(String databaseName, String collectionName,String hostName, int port) {
            @SuppressWarnings("resource")
            MongoClient client = new MongoClient(hostName, port);
            MongoDatabase db = client.getDatabase(databaseName);
            collection = db.getCollection(collectionName);
            System.out.println(collection);
        }
    
        /**
         * 插入一個文檔
         * 
         * @param document  文檔
         */
        public static void insert(Document document) {
            collection.insertOne(document);
        }
    
        /**
         * 查詢全部文檔
         * 
         * @return 全部文檔集合
         */
        public static List<Document> findAll() {
            List<Document> results = new ArrayList<Document>();
            FindIterable<Document> iterables = collection.find();
            MongoCursor<Document> cursor = iterables.iterator();
            while (cursor.hasNext()) {
                results.add(cursor.next());
            }
            return results;
        }
    
        /**
         * 根據條件查詢
         * 
         * @param filter
         *            查詢條件 //注意Bson的幾個實現類,BasicDBObject, BsonDocument,
         *            BsonDocumentWrapper, CommandResult, Document, RawBsonDocument
         * @return 返回集合列表
         */
        public static List<Document> findBy(Bson filter) {
            List<Document> results = new ArrayList<Document>();
            FindIterable<Document> iterables = collection.find(filter);
            MongoCursor<Document> cursor = iterables.iterator();
            while (cursor.hasNext()) {
                results.add(cursor.next());
            }
            return results;
        }
    
        /**
         * 更新查詢到的第一個
         * @param filter  查詢條件
         * @param update  更新文檔
         * @return 更新結果
         */
        public static UpdateResult updateOne(Bson filter, Bson update) {
            UpdateResult result = collection.updateOne(filter, update);
            return result;
        }
    
        /**
         * 更新查詢到的全部的文檔
         * 
         * @param filter 查詢條件
         * @param update 更新文檔
         * @return 更新結果
         */
        public static UpdateResult updateMany(Bson filter, Bson update) {
            UpdateResult result = collection.updateMany(filter, update);
            return result;
        }
    
        /**
         * 更新一個文檔, 結果是replacement是新文檔,老文檔徹底被替換
         * 
         * @param filter 查詢條件
         * @param replacement  跟新文檔
         */
        public static void replace(Bson filter, Document replacement) {
            collection.replaceOne(filter, replacement);
        }
    
        /**
         * 根據條件刪除一個文檔
         * @param filter  查詢條件
         */
        public static void deleteOne(Bson filter) {
            collection.deleteOne(filter);
        }
    
        /**
         * 根據條件刪除多個文檔
         * @param filter 查詢條件
         */
        public static void deleteMany(Bson filter) {
            collection.deleteMany(filter);
        }
    }
  • 編寫mongodb操做測試類

    public class MongoTest {
    
        public static void main(String[] args) {
            MongoDbUtil.connect("test", "jihe1", "*.*.*.*", 27017); // 參數爲 數據庫,集合,ip,端口
    》
    //      testInsert();
    //      testFindAll();
    //      Mongo mg = new Mongo("39.106.131.203",27017);
    //        DB db = mg.getDB("jihe1");
    //        for(String s:db.getCollectionNames()){
    //          System.out.println("內容以下:");
    //            System.out.println(s);
    //        }
    //      
        }
    
        public static void testInsert() {
            Document document = new Document();
            document.append("name", "likang").append("phone", "18912341234");
            MongoDbUtil.insert(document);
        }
    
        public static void testFindAll() {
            List<Document> results = MongoDbUtil.findAll();
            for (Document doc : results) {
                System.out.println(doc.toJson());
            }
        }
    
        public static void testFindBy() {
            Document filter = new Document();
            filter.append("name", "li si");
            List<Document> results = MongoDbUtil.findBy(filter);
            for (Document doc : results) {
                System.out.println(doc.toJson());
            }
        }
    
        public static void testUpdateOne() {
            Document filter = new Document();
            filter.append("phone", "18912341235");
            // 注意update文檔裏要包含"$set"字段
            Document update = new Document();
            update.append("$set", new Document("phone", "123123123"));
            UpdateResult result = MongoDbUtil.updateOne(filter, update);
            System.out.println("matched count = " + result.getMatchedCount());
        }
    
        public static void testUpdateMany() {
            Document filter = new Document();
            filter.append("phone", "18912341235");
            // 注意update文檔裏要包含"$set"字段
            Document update = new Document();
            update.append("$set", new Document("phone", "123123123"));
            UpdateResult result = MongoDbUtil.updateMany(filter, update);
            System.out.println("matched count = " + result.getMatchedCount());
        }
    
        public static void testReplace() {
            Document filter = new Document();
            filter.append("name", "likang");
            // 注意:更新文檔時,不須要使用"$set"
            Document replacement = new Document();
            replacement.append("value", 123);
            MongoDbUtil.replace(filter, replacement);
        }
    
        public static void testDeleteOne() {
            Document filter = new Document();
            filter.append("name", "wang");
            MongoDbUtil.deleteOne(filter);
        }
    
        public static void testDeleteMany() {
            Document filter = new Document();
            filter.append("phone", "18778907890");
            MongoDbUtil.deleteMany(filter);
        }
    }

MongoDB總結

  • Mongodb主要解決的是海量數據的訪問效率問題,根據官方的文檔,當數據量達到50GB以上的時候,Mongo的數據庫訪問速度是MySQL的10倍以上。Mongo的併發讀寫效率不是特別出色,根據官方提供的性能測試代表,大約每秒能夠處理0.5萬-1.5次讀寫請求。由於Mongo主要是支持海量數據存儲的,因此Mongo還自帶了一個出色的分佈式文件系統GridFS,能夠支持海量的數據存儲,最後因爲Mongo能夠支持複雜的數據結構,並且帶有強大的數據查詢功能和相似於sql的索引。

  • Mongodb的高性能在於模式自由,使用高效的二進制數據存儲,包括大型對象(如視頻等)自動處理碎片,以支持雲計算層次的擴展性。在存儲海量數據的同時,還有良好的查詢性能。固然了mongodb支持多種語言,支持RUBY,PYTHON,JAVA,C++,PHP,C#等多種語言

Redis、Memcache、MongoDB特色、區別以及應用場景

https://mp.weixin.qq.com/s?_biz=MzIxMjg4NDU1NA==&mid=2247484268&idx=1&sn=5431c00c451ebeca8aa99ae59f05a3a2&chksm=97be0e49a0c9875fa918412aa0d2544c8dbb02b8875382b08217b1e7818e7ae913d72ae4107c&scene=21#wechatredirect

更多

相關文章
相關標籤/搜索