目錄
-------------------------------------
Nosql數據庫概述
NoSQ數據庫的分類
幾種常見Nosql功能及應用場景介紹
redis簡介
redis應用場景
redis安裝與啓動
redis服務初始化
redis服務啓動與關閉
redis命令行操作
redis的安全設置
redis命令禁用和修改
php程序操作redis服務
php配置session保存到redis
python程序操作redis服務
-------------------------------------
Nosql數據庫概述
NoSQL,意思是“不僅僅是SQL”,泛指非關係型的數據庫。隨着互聯網web2.0網站的興起,傳統的關係數據庫在應付web2.0網站,特別是超大規模和高併發的SNS類型的web2.0純動態網站已經顯得力不從心,暴露了很多難以克服的問題,而非關係型的數據庫則由於其本身的特點得到了非常迅速的發展。NoSQL數據庫的產生就是爲了解決大規模數據集合多重數據種類帶來的挑戰,尤其是大數據應用難題。
NoSQ數據庫的分類
1、Key-Value存儲數據庫
這類數據庫主要會使用到一個哈希表,這個表中有一個特定的鍵和一個指針指向特定的數據。舉例如:Tokyo Tyrant,Redis, memcached,memcachedb,Voldemort,Oracle BDB等。
優點:處理大量數據,快速處理大量讀寫請求,編程友好。
2、列存儲數據庫。
這類數據庫又叫BigTable類型數據庫,通常是用來應對分佈式存儲的海量數據。鍵仍然存在,但是它們的特點是指向了多個列。如:Cassandra,Hbase,Riak。
優點:處理大量數據,應對極高寫負載,高可用,支持跨數據中心
3、文檔型數據庫
同鍵值存儲相類似。該類型的數據模型是版本化的文檔,半結構化的文檔以特定的格式存儲,比如JSON。文檔型數據庫比鍵值數據庫的查詢效率更高。如:CouchDB,MongoDb。
優點:數據模型自然,編程友好,快速開發,web友好。
4、圖形數據庫
圖形結構的數據庫使用靈活的圖形模型,並且能夠擴展到多個服務器上。NoSQ數據庫沒有標準的查詢語言(SQL),因此進行數據庫查詢需要制定數據模型。如:Neo4J,FlockDB ,GraphDB,InfiniteGraph。
優點:可以解決複雜的圖問題。
幾種常見Nosql功能及應用場景介紹
1、Redis
所用語言:C/C++
特點:運行速度異常快
內存數據庫,支持硬盤存儲
主從複製
採用簡單數據或以鍵值索引的哈希表,但也支持複雜操作
支持sets
支持列表
支持哈希表
支持有序sets
Redis支持事務
支持將數據設置成過期數據
發佈訂閱功能允許用戶實現消息機制
最佳應用場景:適用於數據變化快且數據庫大小可遇見(適合內存容量)的應用程序。
例如:實時數據蒐集、數據分析、實時通訊。
2、MongoDB
所用語言:C++
保留了SQL一些友好特性(查詢,索引)。
主從複製
內建分片機制
支持 javascript表達式查詢
可在服務器端執行任意的 javascript函數
在數據存儲時採用內存到文件映射
採用 GridFS存儲大數據或元數據
最佳應用場景:適用於需要動態查詢支持,需要使用索引功能,需要對大數據庫有性能要求。
例如:Web應用
3、HBase
所用語言: Java
特點:支持數十億行,上百萬列
在BigTable之後建模
採用分佈式架構Map/reduce
對實時查詢進行優化
高性能Thrift網關
通過在server端掃描及過濾實現對查詢操作預判
支持 XML, Protobuf, 和binary的HTTP
對配置改變和較小的升級都會重新回滾
不會出現單點故障
堪比MySQL的隨機訪問性能
最佳應用場景:適用於偏好BigTable,並且需要對大數據進行隨機、實時訪問的場合。
例如: Facebook消息數據庫
4、Neo4j
所用語言: Java
基於關係的圖形數據庫
可獨立使用或嵌入到 Java應用程序
圖形的節點和邊都可以帶有元數據
很好的自帶web管理功能
使用多種算法支持路徑搜索
使用鍵值和關係進行索引
爲讀操作進行優化
支持事務
支持在線備份,高級監控及高可靠性
最佳應用場景:適用於圖形一類數據。
例如:公共交通網絡,地圖,網絡拓譜,社交網絡,推薦系統等
redis簡介
redis是一個開源的、使用C語言編寫的、支持網絡交互的、基於內存支持持久化的Key-Value數據庫。redis官網地址,http://redis.io/。
redis應用場景
redis的應用場景有很多,比如顯示最新的項目列表、刪除與過濾、排行榜、計數、實時分析、隊列、緩存等。
國內比較有名的大規模使用redis的場景例如:新浪微博,堪稱史上最大的Redis集羣。
redis安裝與啓動
#到官網下載最新穩定版,本文使用的redis版本是redis-3.0.2
[root@redis ~]# mkdir /home/ju/tools -p [root@redis ~]# cd /home/ju/tools/ [root@redistools]# wget http://110.96.192.8:82/1Q2W3E4R5T6Y7U8I9O0P1Z2X3C4V5B/download.redis.io/releases/redis-3.0.2.tar.gz [root@redistools]# tar xf redis-3.0.2.tar.gz [root@redistools]# cd redis-3.0.2 [[email protected]]# less README [[email protected]]# make [[email protected]]# mkdir /app/redis-3.0.2 –p [[email protected]]# make PREFIX=/app/redis-3.0.2 install [[email protected]]# cd /app/redis-3.0.2/ [[email protected]]# tree . . └── bin ├── redis-benchmark #redis性能測試工具,可以測試在本系統本配置下的讀寫性能 ├── redis-check-aof #對更新日誌appendonly.aof檢查,是否可用 ├── redis-check-dump #用於檢查本地數據庫的rdb文件 ├── redis-cli #redis命令行操作工具,也可以用telnet根據其純文本協議來操作 ├── redis-sentinel -> redis-server └── redis-server #redis服務器的daemon啓動程序 1directory, 6 files [[email protected]]# ln -s /app/redis-3.0.2/ /app/redis [[email protected]]# ll /app/ 總用量 4 lrwxrwxrwx.1 root root 17 7月 12 10:50 redis -> /app/redis-3.0.2/ drwxr-xr-x.3 root root 4096 7月 12 10:48 redis-3.0.2 [[email protected]]# cd /app/redis [[email protected]]#
redis服務初始化
[root@redis redis]# echo "PATH=$PATH:/app/redis/bin/" >> /etc/profile [root@redis redis]# tail -1 /etc/profile PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/app/redis/bin/ [root@redis redis]# . /etc/profile [root@redis redis]# which redis-server /app/redis/bin/redis-server [root@redis redis]# redis-server -h Usage: ./redis-server [/path/to/redis.conf][options] ./redis-server - (read config from stdin) ./redis-server -v or --version ./redis-server -h or --help ./redis-server --test-memory <megabytes> Examples: ./redis-server (run the server with default conf) ./redis-server /etc/redis/6379.conf ./redis-server --port 7777 ./redis-server --port 7777 --slaveof 127.0.0.1 8888 ./redis-server /etc/myredis.conf --loglevel verbose Sentinel mode: ./redis-server /etc/sentinel.conf –sentinel [root@redis redis]# mkdir /app/redis/conf [root@redis redis]# cp /home/ju/tools/redis-3.0.2/redis.conf /app/redis/conf/
redis服務啓動與關閉
[root@redis redis]# redis-server /app/redis/conf/redis.conf & #指定配置文件後臺啓動,端口默認是6379 [1] 13712 [root@redis redis]# 13712:M 12 Jul11:05:52.225 * Increased maximum number of open files to 10032 (it wasoriginally set to 1024). _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.0.2(00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 13712 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 13712:M 12 Jul 11:05:52.229 # Serverstarted, Redis version 3.0.2 13712:M 12 Jul 11:05:52.229 # WARNINGovercommit_memory is set to 0! Background save may fail under low memorycondition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf andthen reboot or run the command 'sysctl vm.overcommit_memory=1' for this to takeeffect. 13712:M 12 Jul 11:05:52.229 # WARNING youhave Transparent Huge Pages (THP) support enabled in your kernel. This willcreate latency and memory usage issues with Redis. To fix this issue run thecommand 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root,and add it to your /etc/rc.local in order to retain the setting after a reboot.Redis must be restarted after THP is disabled. 13712:M 12 Jul 11:05:52.229 # WARNING: TheTCP backlog setting of 511 cannot be enforced because/proc/sys/net/core/somaxconn is set to the lower value of 128. 13712:M 12 Jul 11:05:52.229 * DB loadedfrom disk: 0.000 seconds 13712:M 12 Jul 11:05:52.229 * The server isnow ready to accept connections on port 6379 [root@redis redis]# [root@redis redis]# echo"vm.overcommit_memory = 1" >> /etc/sysctl.conf [root@redis redis]# sysctl -p net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route =0 kernel.sysrq = 0 kernel.core_uses_pid = 1 net.ipv4.tcp_syncookies = 1 net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 68719476736 kernel.shmall = 4294967296 vm.overcommit_memory = 1
overcommit_memory參數說明
設置內存分配策略(可選,根據服務器的實際情況進行設置)
/proc/sys/vm/overcommit_memory
可選值:0、1、2。
0,表示內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,並把錯誤返回給應用進程。
1,表示內核允許分配所有的物理內存,而不管當前的內存狀態如何。
2,表示內核允許分配超過所有物理內存和交換空間總和的內存
注意:redis在dump數據的時候,會fork出一個子進程,理論上child進程所佔用的內存和parent是一樣的,比如parent佔用的內存爲8G,這個時候也要同樣分配8G的內存給child,如果分配的內存不足,可以會造成redis服務器dump數據失敗。所以這裏比較優化的內存分配策略應該設置爲1(表示內核允許分配所有的物理內存,而不管當前的內存狀態如何)。
[root@redis redis]# redis-cli shutdown #關閉redis服務,還可以手動加一個save參數,把內存寫到磁盤 13712:M 12 Jul 11:15:42.218 # Userrequested shutdown... 13712:M 12 Jul 11:15:42.218 * Saving thefinal RDB snapshot before exiting. 13712:M 12 Jul 11:15:42.228 * DB saved ondisk #默認就會把內存數據dump到磁盤 13712:M 12 Jul 11:15:42.228 # Redis is nowready to exit, bye bye... [1]+ Done redis-server /app/redis/conf/redis.conf [root@redis redis]# ls bin conf dump.rdb
redis命令行操作
[root@redis redis]# redis-cli 127.0.0.1:6379> set k1 v1 #設置一個鍵值對 OK 127.0.0.1:6379> get k1 #獲取一個鍵的值 "v1" 127.0.0.1:6379> del k1 #刪除一個鍵 (integer) 1 127.0.0.1:6379> get k1 (nil) 127.0.0.1:6379> EXISTS k1 #判斷這個鍵是否存在,存在返回1,不存在返回0 (integer) 0 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> set k3 v3 OK 127.0.0.1:6379> KEYS * #查看本庫所有的鍵,默認是庫0 1) "k3" 2) "k2" 127.0.0.1:6379> select 1 #切換到庫1,redis默認有16個庫0~15 OK 127.0.0.1:6379[1]> KEYS * (empty list or set) 127.0.0.1:6379[1]> select 15 OK 127.0.0.1:6379[15]> select 16 (error) ERR invalid DB index 127.0.0.1:6379> select 0 OK 127.0.0.1:6379> KEYS * 1) "k3" 2) "k2" 127.0.0.1:6379>quit [root@redis redis]# redis-cli -h192.168.116.204 -p 6379 set k4 v4 OK [root@redis redis]# redis-cli -h192.168.116.204 -p 6379 get k4 "v4" [root@redis redis]# telnet 192.168.116.2046379 Trying 192.168.116.204... Connected to 192.168.116.204. Escape character is '^]'. set k5 v5 +OK get k5 $2 v5 ^] telnet> quit Connection closed. [root@redis redis]# echo "set k6v6" |nc 192.168.116.204 6379 127.0.0.1:6379> get k6 "v6" 127.0.0.1:6379> help #查看幫助 redis-cli 3.0.2 Type: "help @<group>" toget a list of commands in <group> "help <command>" for help on <command> "help <tab>" to get a list of possible help topics "quit" to exit 127.0.0.1:6379> help set #根據命令查看幫助 SETkey value [EX seconds] [PX milliseconds] [NX|XX] summary: Set the string value of a key since: 1.0.0 group: string 127.0.0.1:6379> help @string #根據類型查看幫助 APPEND key value summary: Append a value to a key since: 2.0.0 BITCOUNT key [start] [end] summary:Count set bits in a string since: 2.6.0 此處省略N字 SETRANGE key offset value summary: Overwrite part of a string at key starting at the specifiedoffset since: 2.2.0 STRLEN key summary: Get the length of the value stored in a key since: 2.2.0 127.0.0.1:6379>
redis的安全設置
[root@redis redis]# vim/app/redis/conf/redis.conf …… 387 # Warning: since Redis is pretty fastan outside user can try up to 388 # 150k passwords per second against agood box. This means that you should 389 # use a very strong password otherwiseit will be very easy to break. 390 # 391 # requirepass foobared 392 requirepass feige #在配置文件加上這一行,feige是密碼 …… [root@redis redis]# redis-cli shutdown [root@redis redis]# redis-server/app/redis/conf/redis.conf & #重啓服務 [root@redis redis]# redis-cli 127.0.0.1:6379> KEYS * (error) NOAUTH Authentication required. #此時就需要密碼驗證了 127.0.0.1:6379> auth feige OK 127.0.0.1:6379> KEYS * 1) "k5" 2) "k7" 3) "k6" 4) "k4" 5) "k3" 6) "k2" 127.0.0.1:6379> quit [root@redis redis]# redis-cli -a feige #或者使用此種方法驗證密碼也可以 127.0.0.1:6379> KEYS * 1) "k5" 2) "k7" 3) "k6" 4) "k4" 5) "k3" 6) "k2"
redis命令禁用和修改
[root@redis redis]# vim /app/redis/conf/redis.conf …… 402 # rename-command CONFIGb840fc02d524045429941cc15f59e41cb7be6c52 403 rename-command set "" 404 rename-command get "juget" 405 # It is also possible to completelykill a command by renaming it into 406 # an empty string: 407 # 408 # rename-command CONFIG "" …… [root@redis redis]# redis-cli -a feigeshutdown #由於上一節,所以這裏關閉服務需要驗證密碼了 [root@redis redis]# redis-server/app/redis/conf/redis.conf & (error) ERR unknown command 'set' #這裏就已經提示命令找不到了 127.0.0.1:6379> set k8 v8 (error) ERR unknown command 'set' 127.0.0.1:6379> get k7 (error) ERR unknown command 'get' 127.0.0.1:6379> juget k7 #重命名後的get爲juget可以使用 "v7"
#這裏僅作測試,還是改回原樣吧,生產中可以把一些危險的操作命令改個名或者屏蔽,比如flushdb命令
php程序操作redis服務
[root@redis tools]# wget https://github.com/nicolasff/phpredis/archive/master.zip [root@redis tools]# unzip master.zip [root@redis tools]# cd phpredis-master/ [root@redis phpredis-master]#/app/php/bin/phpize [root@redis phpredis-master]# ./configure--with-php-config=/app/php/bin/php-config [root@redis phpredis-master]# make [root@redis phpredis-master]# make install [root@redis phpredis-master]# ll/app/php-5.6.11/lib/php/extensions/no-debug-non-zts-20131226/ 總用量 2540 -rwxr-xr-x. 1 root root 901139 7月 12 13:24 redis.so [root@redis php]# vim /app/php/lib/php.ini #增加以下兩行 extension_dir = "/app/php-5.6.11/lib/php/extensions/no-debug-non-zts-20131226/" extension = redis.so [root@redis web]# cat redis.php <?php $redis = new Redis(); $redis->connect('192.168.116.204',6379); $redis->auth('feige'); $redis->set('k10', 'v10'); $var = $redis->get('k10'); echo "$var\n"; ?> [root@redis web]# /app/php/bin/phpredis.php v10
#用頁面顯示的這裏就不演示了,沒有CGI環境,有興趣的自己搭個環境測試吧
php配置session保存到redis
phpredis還支持作爲Session的Handler,配置如下:
session.save_handler = redis session.save_path = "tcp://192.168.116.204:6379?weight=1,timeout=2.5
python程序操作redis服務
[root@redis tools]# wget https://pypi.python.org/packages/source/r/redis/redis-2.10.1.tar.gz [root@redis tools]# tar xfredis-2.10.1.tar.gz [root@redis tools]# cd redis-2.10.1 [root@redis redis-2.10.1]# python setup.pyinstall [root@redis redis-2.10.1]# python Python 2.6.6 (r266:84292, Jan 22 2014,09:42:36) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] onlinux2 Type "help","copyright", "credits" or "license" for moreinformation. >>> import redis >>> r =redis.Redis(host='192.168.116.204',port=6379,password='feige',db=0) >>> r.set('k9','v9') True >>> r.get('k9') 'v9' >>> r.keys() ['k4', 'k2', 'k7', 'k3', 'k6', 'k9', 'k5']
今天就寫到這,後續還有關於redis的主從同步、多實例,持久化等一系列博文~