Redis簡介
REmote DIctionary Server(Redis)是一個基於key-value鍵值對的持久化數據庫存儲系統。redis和大名鼎鼎的memcached緩存服務很像,可是redis支持的數據存儲類型更豐富,可是redis支持的數據存儲類型更豐富,包括string(字符串)、list(鏈表),set(集合)和zset(有序集合)等。
這些數據類型都支持push/pop、add/remove及取交集、並集和差集及更豐富的操做,並且這些操做都是原子性的。在此基礎上,redis支持各類不一樣方式的排序。與memchaed緩存服務同樣,爲了保證效率,數據都是緩存在內存中提供服務。而memcached不一樣的是,redis持久化存服務還會週期性的把更新的數據寫入到磁盤以及把修改的操做記錄追加到文件裏記錄下來,比memcached更有優點的是,redis還支持master-slave(主從)同步,這點很相似關係數據庫MySQL。
redis的出現,再必定程序上彌補了memcached這類key-value內存緩存服務的不足,在部分場合能夠對關係數據庫起到很好的補充做用。redis提供了python,ruby,erlang,php客戶端,很方便。
redis官主網站:http://www.redis.io/documentation
http://www.redis.cn/php
Redis的優勢
與memcache不一樣:能夠持久化存儲數據
性能很高:Redis能支持超過100K+每秒的讀寫頻率。
豐富的數據類型:Redis支持二進制的Strings,Lists,Hashes,Sets及Ordered Sets等數據類型操做。
原子:Redis的全部操做都是原子性的,同時Redis還支持對幾個操做全並後的原子性執行。
豐臺的特性:Redis還支持publish/subscribe,通知,key過時等等特性。
redis:支持異機主從複製。html
Redis的數據類型
Redis最爲經常使用的數據類型主要有如下五種:
String
Hash
List
Set
Sorted set
python
Redis的應用場景
傳統的MySQL+Memcached的網站架構遇到的問題
MySQL數據庫其實是適合進行海量數據存儲的,加上經過Memcached將熱點數據存放到內存cache裏,達到加速數據訪問的目的,絕大部分公司都曾經使用過這樣的架構,但隨着業務的數據量的不斷增長和訪問量的持續增加,不少問題就會暴露出來:
一、須要不斷的對MySQL進行拆庫拆表,Memcached也需不斷跟着擴容,擴容和維護工做佔據大量的開發運維時間。
二、Memcached與MySQL數據庫數據一致性問題是個老大難。
三、Memcached數據命中率低或down機,會致使大量訪問直接穿透到數據庫,致使MySQL沒法支撐訪問。
四、跨機房cache同步一致性問題。
Redis的最佳應用場景:
一、Redis最佳試用場景是所有數據in-memory。
二、Redis更多場景是做爲Memcached的替代品來使用。
三、當須要除key/value以外的更多數據類型支持時,使用Redis更合適。
四、支持持久化。
五、須要負載均衡的場景(redis主從同步)
Redis做者談Redis應用場景:http://blog.nosqlfan.com/html/2235.html
業務場景:
使用Redis bitmap進行活躍用戶統計
http://blog.nosqlfan.com/html/3501.html
Redis小節:
一、提升了DB的可擴展性,只須要將新加的數據放到新加的服務器上就能夠了
二、提升了DB的可用性,隻影響到須要訪問的shard服務器上的數據的用戶
三、提供了DB的可維護性,對系統的升級和配置能夠按shard一個個來作,對服務產影響小。git
1、Redis部署環境搭建
Master:任意IP Centos 6.5
Slave:任意IP Centos 6.5github
2、開始安裝Redis服務
在Redis的官方網站(www.redis.io)下載最新的穩定版本redis。
操做命令:redis
- [root@Qinglin-A tools]# wget http://download.redis.io/releases/
- [root@Qinglin-A tools]# tar -xf redis-3.2.2.tar.gz
- [root@Qinglin-A redis-3.2.2]# less README.md
- [root@Qinglin-A redis-3.2.2]# make MALLOC=jemalloc
- [root@Qinglin-A redis-3.2.2]# make PREFIX=/app/redis-3.2.2 install
- [root@Qinglin-A redis-3.2.2]# ln -s /app/redis-3.2.2/ /app/redis
Redis目錄結構sql
- [root@Qinglin-A redis-3.2.2]# tree /app/redis
- /app/redis
- └── bin
- ├── redis-benchmark
- ├── redis-check-aof
- ├── redis-check-rdb
- ├── redis-cli
- ├── redis-sentinel -> redis-server
- └── redis-server
- 1 directory, 6 files
它們的做用以下:
redis-server:redis服務器的daemon啓動程序
redis-cli:Redis命令操做工具。固然,也能夠telnet根據其純文本協助來操做。
redis-benchmark:Redis性能測試工具,測試Redis在你的系統及你的配置下的讀寫性能。
redis-check-aof:更新日誌檢查
redis-check-dump:用於本地數據庫檢查數據庫
3、配置環境變量,並啓動服務
- [root@Qinglin-A redis-3.2.2]# echo 'export PATH=/app/redis/bin:$PATH' >>/etc/profile
- [root@Qinglin-A redis-3.2.2]# tail -1 /etc/profile
- export PATH=/app/redis/bin:$PATH
- [root@Qinglin-A redis-3.2.2]# source /etc/profile
- [root@Qinglin-A redis-3.2.2]# which redis-server
- /app/redis/bin/redis-server
建立Redis配置文件,並重啓服務vim
- [root@Qinglin-A redis-3.2.2]# pwd
- /home/tools/redis-3.2.2
- [root@Qinglin-A redis-3.2.2]# mkdir /app/redis/conf -p
- [root@Qinglin-A redis-3.2.2]# cp redis.conf /app/redis/conf/
- [root@Qinglin-A redis-3.2.2]# redis-server /app/redis/conf/redis.conf & ==>redis啓服務
若是錯誤執行下面的內容api
- [root@Qinglin-A redis-3.2.2]# redis-cli shutdown ==>redis重啓方式
- 提示錯誤"vm.overcommit_memory=1"
- [root@Qinglin-A redis-3.2.2]# sysctl vm.overcommit_memory=1
- 提示錯誤"WARNING you have Transparent Huge Pages (THP) support enabled"
- [root@Qinglin-A redis-3.2.2]# echo 511 > /proc/sys/net/core/somaxconn
- [1]+ Done redis-server /app/redis/conf/redis.conf
- 提示錯誤"WARNING: The TCP backlog setting of 511"
- [root@Qinglin-A redis-3.2.2]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
下列是幫忙文件,能夠指定配置文件啓動服務
- [root@Qinglin-A redis-3.2.2]# redis-server --help
- 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
- 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@Qinglin-A redis-3.2.2]# lsof -i:6379
- COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
- redis-ser 5847 root 4u IPv4 23427 0t0 TCP localhost:6379 (LISTEN)
4、測試Redis
使用redis-cli客戶端
cli幫忙文檔
- [root@Qinglin-A redis-3.2.2]# redis-cli --help
- redis-cli 3.2.2
- Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]]
- -h Server hostname (default: 127.0.0.1).
- -p Server port (default: 6379).
- -s Server socket (overrides hostname and port).
- -a Password to use when connecting to the server.
- -r Execute specified command N times.
- -i When -r is used, waits seconds per command.
- It is possible to specify sub-second times like -i 0.1.
- -n Database number.
- -x Read last argument from STDIN.
- -d Multi-bulk delimiter in for raw formatting (default: \n).
- -c Enable cluster mode (follow -ASK and -MOVED redirections).
- --raw Use raw formatting for replies (default when STDOUT is
- not a tty).
- --no-raw Force formatted output even when STDOUT is not a tty.
- --csv Output in CSV format.
- --stat Print rolling stats about server: mem, clients, ...
- --latency Enter a special mode continuously sampling latency.
- --latency-history Like --latency but tracking latency changes over time.
- Default time interval is 15 sec. Change it using -i.
- --latency-dist Shows latency as a spectrum, requires xterm 256 colors.
- Default time interval is 1 sec. Change it using -i.
- --lru-test Simulate a cache workload with an 80-20 distribution.
- --slave Simulate a slave showing commands received from the master.
- --rdb Transfer an RDB dump from remote server to local file.
- --pipe Transfer raw Redis protocol from stdin to server.
- --pipe-timeout In --pipe mode, abort with error if after sending all data.
- no reply is received within seconds.
- Default timeout: 30. Use 0 to wait forever.
- --bigkeys Sample Redis keys looking for big keys.
- --scan List all keys using the SCAN command.
- --pattern Useful with --scan to specify a SCAN pattern.
- --intrinsic-latency Run a test to measure intrinsic system latency.
- The test will run for the specified amount of seconds.
- --eval Send an EVAL command using the Lua script at .
- --ldb Used with --eval enable the Redis Lua debugger.
- --ldb-sync-mode Like --ldb but uses the synchronous Lua debugger, in
- this mode the server is blocked and script changes are
- are not rolled back from the server memory.
- --help Output this help and exit.
- --version Output version and exit.
- Examples:
- cat /etc/passwd | redis-cli -x set mypasswd
- redis-cli get mypasswd
- redis-cli -r 100 lpush mylist x
- redis-cli -r 100 -i 1 info | grep used_memory_human:
- redis-cli --eval myscript.lua key1 key2 , arg1 arg2 arg3
- redis-cli --scan --pattern '*:12345*'
- (Note: when using --eval the comma separates KEYS[] from ARGV[] items)
- When no command is given, redis-cli starts in interactive mode.
- Type "help" in interactive mode for information on available commands
- and settings.
redis登陸
redis -h主機
- [root@Qinglin-A redis-3.2.2]# redis-cli
- 127.0.0.1:6379>
- 127.0.0.1:6379>
set建立key
set 001工號 qinglin名子
- 127.0.0.1:6379> set no001 qinglin
- OK
get獲取key
- 127.0.0.1:6379> get no001
- "qinglin"
經過遠程獲取key
- [root@Qinglin-A redis-3.2.2]# redis-cli -h 127.0.0.1 -p 6379 get no001
- "qinglin"
刪除key,並查看
- 127.0.0.1:6379> del set no001
- (integer) 1
- 127.0.0.1:6379> get no001
- (nil)
telnet測試方法
- [root@Qinglin-A ~]# telnet 127.0.0.1 6379
- Trying 127.0.0.1...
- Connected to 127.0.0.1.
- Escape character is '^]'.
- set no002 test
- +OK
- get no002
- $4
- test
5、Redis多數據類型介紹
一、字符串類型
這是最簡單的redis類型,若是你只用這種類型,redis就是一個能夠持久化的memcached服務器。
(注:memcache 的數據僅僅保存在內在中,服務器重啓後,數據將丟失)。
- 127.0.0.1:6379> set mykey "my name is guanqinglin"
- OK
- 127.0.0.1:6379> get mykey
- "my name is guanqinglin"
「my name is guanqinglin」 正如你所見到的,一般用SET和GET來設置和獲取字符串值。
值能夠是任何各類類的字符串(包括二進制數據)例如你能夠在一個鍵下保存一副jpeg圖片。值的長度不能超過1GB。
雖然字符串是Redis的基本值類型,可是你仍然能經過它完成一些有趣的操做。
例如:原子遞增
- 127.0.0.1:6379> set counter 100
- OK
- 127.0.0.1:6379> incr counter
- (integer) 101
- 127.0.0.1:6379> incr counter
- (integer) 102
- 127.0.0.1:6379> incr counter 10
- 127.0.0.1:6379> incrby counter 10
- (integer) 112
INCR命令將字符串值解析成整型,將其加1,最後將結果保存爲新的字符串值,數億的命令有INCRBY,DECR and DECRBY。實際上他們在內部就是同一個命令,只是看上去有點不一樣。
二、列表類型
要說清楚列表數據類型,最好先講一點兒理論背景,在信息技術List這個詞經常被使用不當。例如「Python Lists」就名存實亡(名爲Linked Lists),但他們其實是數組(一樣的數據類型在Ruby中叫數組)。
通常意義上講,列表就是有序元素的序列:10,20,1,2,3就是一個例表,但用數組實現的List和Linked List實現的list,在屬性方面大不相同。
Redis lists基於Linked list實現。這意味着即便在一個list中有數百萬個元素,在頭部或尾部添加一個元素的操做,其時間複雜度也是常數級別的。用LPUSH命令在十個元素的list頭部添加新元素,和在千萬元素的list頭部添加新元素的速度相同。
那麼,壞消息是什麼?在數組實現的List中利用索引訪問元素的速度極快,而一樣的操做在linked list實現的list上沒有那麼快。
Redis Lists用linked list實現的緣由是:對於數據庫系統來講,到頭重要的特性是:能很是快的在很大的列表上添加元素,另外一個重要因素是,正如你將要看到的:Redis lists能在常數時間取得常數長度。
Redis lists入門
LPUSH命令可向list的左邊(頭部)添加一個新元素,而RPUSH命令可向list的右邊(尾部)添加一個新元素,最後LRANGE命令可從list中取必定範圍的元素
- 127.0.0.1:6379> RPUSH list1 "Guanqinglin"
- (integer) 1
- 127.0.0.1:6379> RPUSH list1 "Shuaige"
- (integer) 2
- 127.0.0.1:6379> RPUSH list1 "shi"
- (integer) 3
- 127.0.0.1:6379> RPUSH list1 "zhende"
- (integer) 4
- 127.0.0.1:6379> LRANGE list1 0 1
- 1) "Guanqinglin"
- 2) "Shuaige"
- 127.0.0.1:6379> LRANGE list1 0 2
- 1) "Guanqinglin"
- 2) "Shuaige"
- 3) "shi"
- 127.0.0.1:6379> LRANGE list1 0 3
- 1) "Guanqinglin"
- 2) "Shuaige"
- 3) "shi"
- 4) "zhende"
三、Redis集合
Redis集合是未排序的集合,其元素是二進制安全的字符串。SADD命令能夠向集合加添一個新元素。和sets相關的操做也有許多,好比檢測某個元素是否存在,以及實現交集並集,差集等等。一例勝千言:
- 127.0.0.1:6379> SADD myset guan
- (integer) 1
- 127.0.0.1:6379> SADD myset qing
- (integer) 1
- 127.0.0.1:6379> SADD myset lin
- (integer) 1
- 127.0.0.1:6379> SMEMBERS myset
- 1) "guan"
- 2) "lin"
- 3) "qing"
我向集合中添加了三個元素,並讓Redis返回全部元素。如你所見他們是無序的。
如今讓咱們檢查某個元素是否存在:
- 127.0.0.1:6379> SISMEMBER myset guan
- (integer) 1
- 127.0.0.1:6379> SISMEMBER myset shuai
- (integer) 0
guan是這個集合的成員,而shuai不是,集合特別適合表現對像之間的關係,例如用Redis集合能夠很容易實現標籤功能。
5、PHP安裝redis客戶端擴展
獲取源碼包
- [root@Qinglin-A ~]# file master
- master: Zip archive data, at least v1.0 to extract
- [root@Qinglin-A ~]# wget --no-check-certificate https://codeload.github.com/phpredis/phpredis/zip/master
安裝(注本機必須已經安裝PHP程序)
- [root@Qinglin-A ~]# unzip master
- [root@Qinglin-A ~]# cd phpredis-master/
- [root@Qinglin-A /]# /application/php5.3.27/bin/phpize
- Configuring for:
- PHP Api Version: 20090626
- Zend Module Api No: 20090626
- Zend Extension Api No: 220090626
- [root@Qinglin-A phpredis-master]# ./configure --with-php-config=/application/php5.3.27/bin/php-config
- [root@Qinglin-A phpredis-master]# make
- [root@Qinglin-A phpredis-master]# make install
修改php.ini設置,重啓php
- [root@Qinglin-A /]# echo 'extension = redis.so' >>/application/php5.3.27/lib/php.ini
6、redis配置文件介紹及主從同步配置講解
主配置文件
- /app/redis/conf/redis.conf
從庫加上主庫的IP便可實現主從同步
- [root@Qinglin-A /]# vim /app/redis/conf/redis.conf
- # slaveof
- slaveof 10.0.0.1 6379
監控命令(若是從庫執行該命令會一直ping主庫)
- [root@Qinglin-A /]# redis-cli -h localhost -p 6379 monitor
- OK
- 」PING「
redis功能統計
- [root@Qinglin-A /]# redis-cli -h localhost -p 6379 info
- # Server
- redis_version:3.2.2
- redis_git_sha1:00000000
- redis_git_dirty:0
- redis_build_id:cbd0cdda28fdd323
- redis_mode:standalone
- os:Linux 2.6.32-431.el6.x86_64 x86_64
- arch_bits:64
- multiplexing_api:epoll
- gcc_version:4.4.7
- process_id:2457
- run_id:69d1c0246acc88922030a99b8bf9509168123f8d
- tcp_port:6379
- uptime_in_seconds:6192
- uptime_in_days:0
- hz:10
- lru_clock:11052524
- executable:/root/redis-server
- config_file:/app/redis/conf/redis.conf
- # Clients
- connected_clients:1
- client_longest_output_list:0
- client_biggest_input_buf:0
- blocked_clients:0
- # Memory
- used_memory:821984
- used_memory_human:802.72K
- used_memory_rss:2732032
- used_memory_rss_human:2.61M
- used_memory_peak:821984
- used_memory_peak_human:802.72K
- total_system_memory:1036648448
- total_system_memory_human:988.62M
- used_memory_lua:37888
- used_memory_lua_human:37.00K
- maxmemory:0
- maxmemory_human:0B
- maxmemory_policy:noeviction
- mem_fragmentation_ratio:3.32
- mem_allocator:jemalloc-4.0.3
- # Persistence
- loading:0
- rdb_changes_since_last_save:0
- rdb_bgsave_in_progress:0
- rdb_last_save_time:1470666679
- rdb_last_bgsave_status:ok
- rdb_last_bgsave_time_sec:0
- rdb_current_bgsave_time_sec:-1
- aof_enabled:0
- aof_rewrite_in_progress:0
- aof_rewrite_scheduled:0
- aof_last_rewrite_time_sec:-1
- aof_current_rewrite_time_sec:-1
- aof_last_bgrewrite_status:ok
- aof_last_write_status:ok
- # Stats
- total_connections_received:3
- total_commands_processed:42
- instantaneous_ops_per_sec:0
- total_net_input_bytes:1744
- total_net_output_bytes:17746419
- instantaneous_input_kbps:0.00
- instantaneous_output_kbps:0.00
- rejected_connections:0
- sync_full:0
- sync_partial_ok:0
- sync_partial_err:0
- expired_keys:0
- evicted_keys:0
- keyspace_hits:11
- keyspace_misses:1
- pubsub_channels:0
- pubsub_patterns:0
- latest_fork_usec:293
- migrate_cached_sockets:0
- # Replication
- role:master
- connected_slaves:0
- master_repl_offset:0
- repl_backlog_active:0
- repl_backlog_size:1048576
- repl_backlog_first_byte_offset:0
- repl_backlog_histlen:0
- # CPU
- used_cpu_sys:9.77
- used_cpu_user:4.39
- used_cpu_sys_children:0.01
- used_cpu_user_children:0.00
- # Cluster
- cluster_enabled:0
- # Keyspace
- db0:keys=3,expires=0,avg_ttl=0
或查看單個CPU的內容
- [root@Qinglin-A /]# redis-cli -h localhost -p 6379 info CPU
- # CPU
- used_cpu_sys:9.83
- used_cpu_user:4.44
- used_cpu_sys_children:0.01
- used_cpu_user_children:0.00