在命令行執行下面的命令:node
$ wget http://download.redis.io/releases/redis-2.8.13.tar.gz $ tar xzf redis-2.8.13.tar.gz $ cd redis-2.8.13 $ make
編譯完成後,會產生六個文件:git
redis-server
:這個是redis的服務器github
redis-cli
:這個是redis的客戶端redis
redis-check-aof
:這個是檢查AOF文件的工具算法
redis-check-dump
:這個是本地數據檢查工具數據庫
redis-benchmark
:性能基準測試工具,安裝完後能夠測試一下當前Redis的性能vim
redis-sentinel
:Redis監控工具,集羣管理工具promise
Redis的配置文件是:redis.conf
經常使用配置項爲:緩存
`daemonize`: 是否之後臺進程運行,默認爲no `pidfile /var/run/redis.pid `: pid文件路徑 `port 6379`: 監聽端口 `bind 127.0.0.1`:綁定主機ip `unixsocket /tmp/redis.sock`:sock文件路徑 `timeout 300`:超時時間,默認是300s `loglevel verbose`:日誌等級,可選項有debug:大量的信息,開發和測試有用;verbose:不少極其有用的信息,可是不像debug那麼亂;notice:在生產環境中你想用的信息;warning:最關鍵、最重要的信息纔打印。 默認是erbose `logfile stdout`:日誌記錄方式,默認是stdout `syslog-enabled no`:日誌記錄到系統日誌中,默認是no `syslog-ident redis`:指定系統日誌標識 `syslog-facility local0`:指定系統日誌設備,必須是USER或者 LOCAL0~LOCAL7。 默認是local0 `databases 16`:數據庫的數量,默認的數據庫是DB 0,你可使用 SELECT <dbid> 來選擇不一樣的數據庫。dbid的範圍是0~(你設置的值-1) `save <seconds> <changes>`:RDB在多長時間內,有多少次更新操做,就將數據同步到數據文件。 `save 900 1`:15min內至少1個key被改變 `save 300 10`:5min內至少有300個key被改變 `save 60 10000`:60s內至少有10000個key被改變 `rdbcompression yes`:存儲至本地數據庫時是否壓縮數據,默認是yes `dbfilename dump.rdb`:本地數據庫文件名,默認是dump.rdb `dir ./`:本地數據庫存放路徑,默認是./ `slaveof <masterip> <masterport>`:當本機爲從服務時,設置主服務的ip以及端口 `masterauth <master-password>`:主服務的鏈接密碼 **從結點與主結點失去鏈接、或者正在複製時,從結點對客戶端請求的處理方式:** `slave-serve-stale-data yes`:yes:從結點繼續響應客戶端的請求,可是數據有可能不許確或者爲空 no:除了INFO和SLAVEOF之外,其它的命令都返回「SYNC with master in progress」 `requirepass foobared`:鏈接密碼foobared `maxclients 128`:最大鏈接數,默認不限制 `maxmemory <bytes>`:設置最大內存,達到最大內存設置後,redis會先嚐試清除已到期或即將到期的key,當此方法處理後,任然到達最大內存設置,將沒法再進行寫入操做 ** 下面是maxmemory的策略 ** `maxmemory-policy volatile-lru `:maxmemory設置策略,默認是volatile-lru volatile-lru:使用LRU算法,從過時集中移除 allkeys-lru:根據LRU算法移除key volatile-random:從過時集中隨機移動一個 allkeys-random:隨機移除一個 volatile-ttl: 根據最近過時時間移除key noeviction:不移除數據,客戶端寫操做時返回錯誤 don't expire at all, just return an error on write operations `maxmemory-samples 3` `appendonly no`:是否 在每次更新操做後進行日誌記錄,若是不開啓,可能會在斷電時致使一段時間內的數據丟失。由於redis自己同步數據文件是按照上面save條件來進行同步的,因此有的數據會在一段時間內只存在於內存中。默認是no `appendfilename appendonly.aof`:更新日誌文件名,默認是appendonly.aof redis支持的三種不一樣的同步方式: no: don't fsync, just let the OS flush the data when it wants. Faster. //等待OS進行數據緩存同步到硬盤 always: fsync after every write to the append only log . Slow, Safest. //每次更新操做後調用fsync()將數據寫到磁盤 everysec: fsync only if one second passed since the last fsync. Compromise. //每秒同步一次 `appendfsync everysec` //更新日誌條件,默認是everysec `no-appendfsync-on-rewrite no` `slowlog-log-slower-than 10000`:設置redis slow log時間,只包括命令執行時間,不包括IO操做時間,好比客戶端鏈接,應答相應時間等等。單位是microseconds(一百萬分之一秒),默認是10000.負值表示禁用slow log,0表示記錄全部命令。 `slowlog-max-len 1024`:slowlog最大長度1024.這會消耗內存,使用SLOWLOG RESET來回收slowlog內存。 `vm-enabled no` //是否使用虛擬內存,默認是no。在redis2.4版本,強烈不建議使用virtual memory。 `vm-swap-file /tmp/redis.swap` //虛擬內存文件路徑,默認是/tmp/redis.swap,不可多個redis實例共享虛擬內存文件。 `vm-max-memory 0` //設置最大vm,默認爲0,全部的value存在於磁盤中。 `vm-page-size 32` //設置vm的page大小,默認是32 `vm-pages 134217728` //設置swap文件中最大memory pages,默認是134217728。swap大小=vm-page-size * vm-pages `vm-max-threads 4` //vm同時運行的最大io線程
指定在超過必定的數量或者最大的元素超過某一臨界值時,採用一種特殊的哈希算法:安全
`hash-max-zipmap-entries 512` `hash-max-zipmap-value 64` `list-max-ziplist-entries 512` `list-max-ziplist-value 64` `set-max-intset-entries 512` `activerehashing yes` //是否重置hash表 `include /path/to/other.conf`:引用其餘配置文件
設置Linux內核內存分配策略
$ sudo vim /etc/sysctl.conf
vm.overcommit_memory = 1
//指定內核針對內存分配的策略,其值能夠是0,1,2
0表示內核將檢查是否有足夠的可用內存供應用進程使用;若是有足夠的可用內存,內存申請容許;不然,內存申請失敗,並把錯誤返回給應用進程。 1表示內核容許分配全部的物理內存,而無論當前的內存狀態如何。 2表示內核容許分配超過全部物理內存和交換空間總和的內存
./redis-server redis.conf
若是想在一臺服務器上搭建多個實例,可使用下面的目錄結果:
redis |-- 根目錄下放置文件 |-- instance-1 實例1的目錄 |-- redis.conf 實例1的配置文件 |-- instance-2 實例2的目錄 |-- redis.conf 實例2的配置文件 |-- instance-3 實例3的目錄 |-- redis.conf 實例3的配置文件
啓動時可使用下面的命令:
./redis-server ./instance-1/redis.conf
:啓動實例1 ./redis-server ./instance-2/redis.conf
:啓動實例2 ./redis-server ./instance-3/redis.conf
:啓動實例3
./redis-benchmark
經過基準測試,能夠測試在當前的Redis服務器的性能。我在個人虛擬機上測試的結果是寫每秒4萬多,讀每秒8萬多
在做爲副本的Redis服務器的配置文件中增長以下配置: slaveof 192.168.66.41 6379
說明: salveof <主結點的IP> <主結點的端口>
#Jedis客戶端使用
Jedis的github地址爲: https://github.com/xetorthio/jedis
能夠經過下面兩種方式來獲取Jedis的Jar包
https://github.com/xetorthio/jedis/releases
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.5.2</version> <type>jar</type> <scope>compile</scope> </dependency>
Jedis jedis = new Jedis("localhost"); jedis.set("foo", "bar"); String value = jedis.get("foo");
固然,這種方式並很差,由於每次使用都要新創建一個鏈接,並且Jedis並非線程安全的,在併發訪問的狀況下容易出奇怪的問題。因此應該使用下面的這種方式:使用池
來作。
JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost"); Jedis jedis = pool.getResource(); try { /// 開始使用 jedis.set("foo", "bar"); String foobar = jedis.get("foo"); jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike"); Set<String> sose = jedis.zrange("sose", 0, -1); } finally { /// 使用完後,將鏈接放回鏈接池 if (null != jedis) { jedis.close(); } } /// 應用退出時,關閉鏈接池: pool.destroy();
這種使用池的方式通常都能知足咱們的要求,可是有時候咱們使用多臺Redis服務器時,咱們須要將不一樣的key放到不一樣的Redis服務器上面,這時咱們能夠根據業務的不一樣來選擇不一樣的Redis服務器。這麼作能夠必定程度的解決問題,可是還會有另外的問題生產,如:咱們不容易肯定哪一個業務產品的數據有多大。這樣會使數據不能平均的分配到多臺Redis服務器上面。 這時咱們須要使用分片的技術。代碼以下:
// 分片信息 List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); JedisShardInfo si = new JedisShardInfo("localhost", 6379); si.setPassword("foobared"); shards.add(si); si = new JedisShardInfo("localhost", 6380); si.setPassword("foobared"); shards.add(si); // 池對象 ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); // 開始使用 ShardedJedis jedis = pool.getResource(); jedis.set("a", "foo"); .... // do your work here pool.returnResource(jedis); .... // a few moments later ShardedJedis jedis2 = pool.getResource(); jedis.set("z", "bar"); pool.returnResource(jedis); pool.destroy();
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>(); //Jedis Cluster will attempt to discover cluster nodes automatically jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7379)); JedisCluster jc = new JedisCluster(jedisClusterNodes); jc.set("foo", "bar"); String value = jc.get("foo");