IT|軟體|資料庫|Key-Value|Redis| Cluster 集群伺服器設定

Redis 集群提供了以下兩個好處

#將數據自動切分(split)到多個節點的能力。
#當集群中的一部分節點失效或者無法進行通訊時,仍然可以繼續處理命令請求的能力。
 
Redis 架構

架構細節:
(1)所有的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬.
(2)節點的fail是通過集群中超過半數的節點檢測失效時才生效.
(3)客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連接集群所有節點,連接集群中任何一個可用節點即可
(4)redis-cluster把所有的物理節點映射到[0-16383]slot上,cluster負責維護node<->slot<->value
 
 
 
Redis Cluster 搭建與使用

要讓集群正常工作至少需要3個主節點,在這裡我們要創建6個redis節點,其中三個為主節點,三個為從節點,對應的redis節點的ip和端口對應關係如下(為了簡單演示都在同一台機器上面)。
127.0.0.1:7000
127.0.0.1:7001
127.0.0.1:7002
127.0.0.1:7003
127.0.0.1:7004
127.0.0.1:7005
 
 
[安裝 redis]
 
創建存放多個實例的目錄
mkdir /home/pi/data/cluster -p
cd /home/pi/data/cluster
mkdir 7000 7001 7002 7003 7004 7005
 
修改配置文件
樹莓派
cp /etc/redis.conf /home/pi/data/cluster/7000/

Linux
cp /home/pi/redis-4.0.2/redis.conf /home/pi/data/cluster/7000/

修改以下選項(修改完成後,把修改完成的redis.conf複製到7001-7005目錄下,並且端口修改成和文件夾對應):
port 7000
daemonize yes —> 即默認以後台程序方式運行
cluster-enabled yes  —> 文件中的cluster-enabled選項用於開實例的集群模式
cluster-config-file nodes.conf —> cluster-conf-file選項則設定了保存節點配置文件的路徑,默認值為nodes.conf
cluster-node-timeout 5000
appendonly yes—> 開啟 AOF 模式

複製 redis.conf 到以下目錄並改寫 port(7001、7002、7003、7004、7005 )

cp /home/pi/data/cluster/7000/redis.conf /home/pi/data/cluster/7001/
cp /home/pi/data/cluster/7000/redis.conf /home/pi/data/cluster/7002/
cp /home/pi/data/cluster/7000/redis.conf /home/pi/data/cluster/7003/
cp /home/pi/data/cluster/7000/redis.conf /home/pi/data/cluster/7004/
cp /home/pi/data/cluster/7000/redis.conf /home/pi/data/cluster/7005/

按上述步驟重複修改 port 屬性
 
分別啟動 6 個 redis 實例
 
樹莓派
#0
cd /home/pi/data/cluster/7000
redis-server redis.conf
#1
cd /home/pi/data/cluster/7001
redis-serverredis.conf
#2
cd /home/pi/data/cluster/7002
redis-serverredis.conf
#3
cd /home/pi/data/cluster/7003
redis-serverredis.conf
#4
cd /home/pi/data/cluster/7004
redis-serverredis.conf
#5
cd /home/pi/data/cluster/7005
redis-server redis.conf
 
查看進程是否存在
ps -ef | grep redis
 
 
檢查是否端口為進程
netstat -npl
 
[執行命令創建 cluster]
 
安裝ruby相關的環境,否則創建集群可能會失敗
sudo apt-get install rubygems
 
安裝運行需要依賴的ruby的包gem-redis

必須與 redis 安裝版本一致 
cd ~
gem install -l redis-4.0.1.gem
 
異常處理

 
gem-redis 必需搭配 Ruby 2.2 以上版本
研究-RVM、ruby
複製集群管理程序到/usr/local/bin
cd /home/pi/Downloads/redis-4.0.1
sudo cp /home/pi/Downloads/redis-4.0.1/src/redis-trib.rb /usr/local/bin/redis-trib
 
創建集群
執行前先確定 aof、rdb、nodes.conf 個別資料夾已先刪除
192.168.43.176
redis-trib create --replicas 1 192.168.43.176:7000 192.168.43.176:7001 192.168.43.176:7002 192.168.43.176:7003 192.168.43.176:7004 192.168.43.176:7005

127.0.0.1
redis-trib create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

異常處理
pi@MyPi1:/usr/local/bin $ redis-trib create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
>>> Creating cluster

[ERR] Node 127.0.0.1:7000 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

解決辦法
將每個節點下aof、rdb、nodes.conf本地備份文件刪除 (7000、7001、7002、7003、7004、7005)
之後再執行此腳本,成功執行
 
命令的意義如下:
*給定redis-trib.rb程序的命令是create,這表示我們希望創建一個新的集群。
*選項–replicas 1表示我們希望為集群中的每個主節點創建一個從節點。
*之後跟著的其他參數則是實例的地址列表,我們希望程序使用這些地址所指示的實例來創建新集群。
簡單來說,以上命令的意思就是讓redis-trib程序創建一個包含三個主節點和三個從節點的集群。
接著,redis-trib會打印出一份預想中的配置給你看,如果你覺得沒問題的話,就可以輸入yes,redis-trib就會將這份配置應用到集群當中:
 
 
輸入yes並按確認之後,集群就會將配置應用到各個節點,並連接起(join)各個節點,各個節點開始互相通訊
 
 
一切正常後輸出以下信息
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
 
測試Redis集群比較簡單的辦法就是使用redis-rb-cluster或者redis-cli,接下來我們將使用redis-cli為例來進行演示:
redis-cli -c -p 7001
set name kevin
get name
 
 
可以查詢相關指令透過以下命令:可以看見有add-node,不用想了,肯定是添加節點。那麼del-node就是刪除節點。還有check肯定就是檢查狀態了。
[root@redis-server ~]# redis-trib help
Usage: redis-trib <command> <options> <arguments ...>

  set-timeout     host:port milliseconds
  add-node        new_host:new_port existing_host:existing_port
                  --master-id <arg>
                  --slave
  fix             host:port
  help            (show this help)
  del-node        host:port node_id
  import          host:port
                  --from <arg>
  check           host:port
  call            host:port command arg arg .. arg
  create          host1:port1 ... hostN:portN
                  --replicas <arg>
  reshard         host:port
                  --yes
                  --to <arg>
                  --from <arg>
                  --slots <arg>

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
[root@redis-server ~]#
 
可以看到7000-7002是master,7003-7005是slave。
redis-cli -h 192.168.43.176 -p 7000 cluster nodes
 
 
[故障轉移測試]
 
可以看見7001是正常的,並且獲取到了key,value,現在kill掉7000實例,再進行查詢。
[root@redis-server ~]# ps -ef | grep 7000
root      4168     1  0 11:49 ?        00:00:03 redis-server *:7000 [cluster]
root      4385  4361  0 12:39 pts/3    00:00:00 grep 7000
[root@redis-server ~]# kill 4168
[root@redis-server ~]# ps -ef | grep 7000
root      4387  4361  0 12:39 pts/3    00:00:00 grep 7000
[root@redis-server ~]# redis-cli -c -p 7001
127.0.0.1:7001> get name
"yayun"
127.0.0.1:7001>
 
可以正常獲取到value,現在看看狀態。
[root@redis-server ~]# redis-cli -c -p 7001 cluster nodes
2d03b862083ee1b1785dba5db2987739cf3a80eb 127.0.0.1:7001 myself,master - 0 0 2 connected 5461-10922
0456869a2c2359c3e06e065a09de86df2e3135ac 127.0.0.1:7002 master - 0 1428295271619 3 connected 10923-16383
37b251500385929d5c54a005809377681b95ca90 127.0.0.1:7003 master - 0 1428295270603 7 connected 0-5460
e2e2e692c40fc34f700762d1fe3a8df94816a062 127.0.0.1:7004 slave 2d03b862083ee1b1785dba5db2987739cf3a80eb 0 1428295272642 5 connected
2774f156af482b4f76a5c0bda8ec561a8a1719c2 127.0.0.1:7000master,fail- 1428295159553 1428295157205 1 disconnected
9923235f8f2b2587407350b1d8b887a7a59de8db 127.0.0.1:7005 slave 0456869a2c2359c3e06e065a09de86df2e3135ac 0 1428295269587 6 connected
[root@redis-server ~]#
原來的7000端口實例已經顯示fail,原來的7003是slave,現在自動提升為master。
關於更多的在線添加節點,刪除節點,以及對集群進行重新分片請參考官方文檔。
 
 
[Java 集群測試]
 
使用Java客戶端對Redis進行操作
packagecom.agile.example.redis;

importjava.io.IOException;
importjava.util.HashSet;

importredis.clients.jedis.HostAndPort;
importredis.clients.jedis.JedisCluster;

/**
 *Redisclusetertest
 *
 *@authorKevin
 *@date2017-11-16
 */

publicclassRedisClusterTest {

publicstaticvoidmain(String[]args)throwsIOException {

HashSet<HostAndPort>nodes=newHashSet<HostAndPort>();
nodes.add(newHostAndPort("192.168.43.176", 7000));
nodes.add(newHostAndPort("192.168.43.176", 7001));
nodes.add(newHostAndPort("192.168.43.176", 7002));
nodes.add(newHostAndPort("192.168.43.176", 7003));
nodes.add(newHostAndPort("192.168.43.176", 7004));
nodes.add(newHostAndPort("192.168.43.176", 7005));

JedisClustercluster=newJedisCluster(nodes);
cluster.set("jedisClusterKey","hello world");
Stringstr=cluster.get("jedisClusterKey");
System.out.println("---"+str);

cluster.close();// 關閉連接

  }
}
 
參考資源

 
 
 
 
 
 
 
 
 

IT|資料庫|PostgreSQL 安裝於 Mac OS、Ubuntu Linux

PostgreSQL 介紹

PostgreSQL是以加州大學伯克利分校計算機系開發的POSTGRES版本4.2為基礎的對象關係型數據庫管理系統(ORDBMS),簡稱 pgsql,是一個自由的對象-關係數據庫服務器,由社區驅動的的對象-關係型數據庫系統,它支持大部分SQL標準並且提供了許多其他現代特性,它在靈活的BSD-風格許可證下發行.越來越多的人用它來取代mysql 。已成為開發首選的開源關係型數據庫。
 
 
安裝 PostgreSQL

 
[安裝標的:Mac OS X]
 
在 MAC 環境下,除了可以使用brew安裝,也可以直接從網路下載安裝檔來安裝,本例以安裝檔作為安裝示範。
 
PostgreSQL 官網下載地址:選擇 Mac OS X版本下載,直接安裝即可。
 
在安裝的過程中系統會自動為生成一個賬號 PostgreSQL,密碼隨機。
 
所以需要要重設密碼,可透過上面 GUI 介面重設,或透過控制台以指令方式重設
sudo passwd -d postgres
 
#指令說明
password  -d 为删除指定用户密码
 
設置新密碼
sudo -u postgres passwd
然後就可以用postgres用戶在服務器上通過pgAdmin或者psql來操作資料庫了。
 
[執行 SOL Shell]
 
執行SQL Shell (psql)啓動程式
Server [localhost]:    //第一步,默認 localhost,遠端資料庫,請輸入遠端服務器 IP
Database [postgres]:   //第二步,執行資料庫, postgresql安裝時已經默認安裝postgres數據庫
Port [5432]:           //第三步,默認綁定5432端口,如果有修改請在這裡指定,否則默認連接此端口(注意防火牆放行端口)
Username [postgres]:   //第四步,默認使用postgres用戶登錄資料庫,沒有指定用戶的話
psql (9.4.1)
Type "help" for help.

postgres=#     //看到這一步,已經成功進入postgres 資料庫.
 
或者可以用下面一條命令來登錄PostgreSQL
psql -U postgres -d postgres -h 127.0.0.1 -p 5432

參數說明:
-U指定用戶    -d指定資料庫  -h 資料庫服務器 IP    -p端口
如果你的系統登錄帳號和 PostgreSQL 數據庫操作用戶名相同的話,可以省略-U參數。
 
若遇到Mac命令控制台不支持psql指令,則需要手動添加到全局環境變數
$ locate psql | grep /bin
/Library/PostgreSQL/9.4/bin/psql
 
編輯 .bash_profile 文件或 .bashrc 文件,添加命令別名
alias psql=/Library/PostgreSQL/9.4/bin/psql
 
然後讓 .bash_profile 生效即可
source .bash_profile
 
 
[安裝標的:Linux]
 
PostgreSQL 官網下載地址:選擇 Ubuntu 版本下載,直接安裝即可。這裡我們以Ubuntu 16.04 LTS為例,如果你的操作系統不一樣,可以去官網上找不同平台的安裝指南。
 
Create the file /etc/apt/sources.list.d/pgdg.list, and add a line for the repository
$ vim /etc/apt/sources.list.d/pgdg.lis
 
在檔案內添加這一行
deb http://apt.postgresql.org/pub/repos/apt/ YOUR_UBUNTU_VERSION_HERE-pgdg main

#YOUR_UBUNTU_VERSION_HERE-pgdg 為 UBUNTU 版本,以我安裝的 Ubuntu 16.04 LTS 為例,可以是如下的指令
deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main
Import the repository signing key, and update the package lists
$ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
  sudo apt-key add -
$ sudo apt-get update
安裝pg,注意版本號可以自己指定,目前最新穩定版是9.6(2017-12-26 )
$ apt-get install postgresql-9.6
 
安裝完之後,Linux系統中多了一個用戶postgres。同時pg數據庫也會創建一個數據庫用戶,用戶名也叫postgres。還會創建一個數據庫,資料庫名也是叫postgres。
 
 
我們切換到postgres用戶,然後直接連一下數據庫看看:
$ su - postgres
$ psql
系統提示符變成了 postgres=#,表示已經成功登錄到了名為 postgres 的資料庫。
 
psql 簡單的操作指令

\h select。
\? 查看psql命令列表。
\l 列出所有資料庫。
\c [database_name]:連接其他資料庫。
\d 列出當前資料庫的所有表格。
\d [table_name]:列出某一張表格的結構。
\du 列出所有用戶。
\e 打開文字編輯器。
\conninfo 列出當前資料庫和連接的資訊。
\q  退出
\password  設置命令
 
# 創建新表
CREATE TABLE user_tbl(name VARCHAR(20), signup_date DATE);
# 插入資料
INSERT INTO user_tbl(name, signup_date) VALUES('張三', '2013-12-22');
# 選擇記錄
SELECT * FROM user_tbl;
# 更新資料
UPDATE user_tbl set name = '李四' WHERE name = '張三';
# 刪除記錄
DELETE FROM user_tbl WHERE name = '李四' ;
# 添加欄位
ALTER TABLE user_tbl ADD email VARCHAR(40);
# 更新結構
ALTER TABLE user_tbl ALTER COLUMN signup_date SET NOT NULL;
# 更名欄位
ALTER TABLE user_tbl RENAME COLUMN signup_date TO signup;
# 刪除欄位
ALTER TABLE user_tbl DROP COLUMN email;
# 表格更名
ALTER TABLE user_tbl RENAME TO backup_tbl;
# 刪除表格
DROP TABLE IF EXISTS backup_tbl;
 
pg 規則

命令行客戶端psql有個規則,就是當登錄命令沒指定數據庫用戶的時候,會以當前系統用戶同名的數據庫用戶來登錄,此時視為已經具備了該數據庫用戶的身份,因此登錄時無需輸入密碼。這叫做IDENT/PEER authentication。
 
另外還有個規則,如果登錄時不指定數據庫,會嘗試登錄與用戶名同名的數據庫。
 
知道這兩條規則,就不難理解為什麼剛剛不指定用戶名密碼和數據庫就成功登上了。
 
自動創建的數據庫用戶postgres是超級用戶,這個用戶權限一旦被攻破後果不堪設想。因此,自動創建的同名系統用戶postgres的權限安全也就同樣重要,所以該用戶默認是不能以用戶名密碼登錄操作系統的,此乃故意為之。具體原因這個帖子有解釋。
 
一般超級用戶postgres只用來做管理,其他所有事情最好創建專門的數據庫用戶去做。注意psql里執行每條語句都要以分號結束。
 
 
創建用戶(注意密碼用單引號括起來)

創建好用戶後,創建一個屬於這個用戶的資料庫:
postgres=# create user <user> with password '<password>';
 
創建完資料庫用戶,再創建一個同名的系統用戶:
postgres=# create database <database> owner <user>;
 
切換成這個系統用戶,就可以登錄資料庫
$ adduser <user>
 
遠程連接配置
$ su - <user>
$ psql -d <database>
 
 
允許遠端登入資料庫

默認只允許從本機登錄,如果要遠程連接資料庫,需要改兩個配置文件。
 
修改配置文件
$ vim /etc/postgresql/9.6/main/postgresql.conf

#把監聽地址由默認的 localhost 改成 *
listen_addresses = '*'
 
修改配置文件
$ vim /etc/postgresql/9.6/main/pg_hba.conf

#允許某個用戶從任何遠程主機連接某個數據庫:
#host    <database>   <user>     all    md5
#允許所有用戶從任何遠程主機連接所有數據庫:
host    all         all         all    md5

#在文件中添加一行,把允許哪個用戶訪問哪個數據庫寫進去,如果怕麻煩不想挨個做限制,也可以寫成all。
#hba,這幾個字母的意思是host based authorization,就是對主機進行細粒度的訪問控制。
 
改完這兩個配置文件,需要重啓服務才能生效(注意配置文件中不要有語法錯誤,否則服務不聲不響地起不來,也不報錯。我在設定時犯了點錯,因為在pg_hba.conf添加的那行結尾多了個分號,浪費了不少時間。)
$ service postgresql restart
 
大功告成!