LieBrother

当才华撑不起野心时,应该静下心来学习;当能力驾驭不了目标时,应该沉下心来历练。


  • 首页

  • 归档

  • 分类

  • 标签

  • 关于

Redis基本命令

发表于 2016-03-24   |   分类于 Redis   |     |   阅读次数

set/get命令(如果已经存在该key,则替换)

1
2
3
4
> set key "abc"
OK
> get key
"abc"

如果健存在,则执行失败;如果健不存在,则执行成功:

1
2
3
4
> set key newval nx
(nil)
> set key newval xx
OK

设置Integer值,原子性增减

1
2
3
4
5
6
7
8
9
10
11
12
> set count 100
OK
> incr count
(integer)101
> incr count
(integer)102
> incrby count 50
(integer)152
> decr count 2
(integer)150
> decrby count 50
(integer)100

mset/mget命令

1
2
3
4
5
6
> mset a 10 b 20 c 30
OK
> mget a b c
1) "10"
2) "20"
3) "30"

exists命令【返回1表示数据库中存在,返回0表示数据库中不存在】

1
2
3
4
5
6
7
8
> set mykey hello
OK
> exists mykey
(integer) 1
> del mykey
(integer) 1
> exists mykey
(integer) 0

type命令【返回某个键的值的类型】

1
2
3
4
5
6
7
8
> set key x
OK
> type key
string
> del key
(integer) 1
> type key
none

expire命令
过期时间可以设置为秒或者毫秒精度。
过期时间分辨率总是 1 毫秒。
过期信息被复制和持久化到磁盘,当 Redis 停止时时间仍然在计算 (也就是说 Redis 保存了过期时间)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
> set key "expire"
OK
> expire key 5
(integer) 1
> get key
"expire"
> get key //5秒过后
(nil)
//设置过期时间 10 秒
> set key 100 ex 10
OK
//查看剩余时间
> ttl key
(integer) 6
> ttl key
(integer) 3
//设置毫秒级,用pexpire/pttl命令
>set key "expire"
OK
> pexpire key 10000
(integer) 1
> pttl key
(integer) 4107
> pttl key
(integer) 1108

lpush / rpush / lrange / lpop / rpop 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//rpush 从右边添加一个元素
> rpush list A
(integer) 1
> rpush list B
(integer) 2
//lpush 从左边添加一个元素
> lpush list C
(integer) 3
//lrange x[开始元素] y[结束元素] 可以是负数,-1表示最后一个元素,-2表示倒数第二个元素
> lrange list 0 -1
1) "C"
2) "A"
3) "B"
> lrange list 0 1
1) "C"
2) "A"
> lrange list 0 2
1) "C"
2) "A"
3) "B"
//可以同时添加多个元素
> rpush mlist 1 2 3 4 5 6 "abc"
(integer) 7
> lrange mlist 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "abc"
//lpop 从左边弹出元素
> lpop mlist
"1"
//rpop 从右边弹出元素
> rpop mlist
"abc"

ltrim 命令

1
2
3
4
5
6
7
8
9
> rpush nlist 1 2 3 4 5
(integer) 5
//保存0 - 2 的元素,其他元素丢弃掉
> ltrim nlist 0 2
OK
> lrange nlist 0 -1
1) "1"
2) "2"
3) "3"

列表阻塞操作
BRPOP 和 BLPOP 两个命令
它们是当列表为空时 RPOP 和 LPOP 的会阻塞版本:仅当
一个新元素被添加到列表时,或者到达了用户的指定超时时间,才返回给调用者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//先将tasks填入元素
> rpush tasks 1 2 3
(integer) 3
//如果tasks有元素,则弹出右边的一个元素,如果tasks无元素,则等待5秒,如果5秒内没有元素添加到tasks,则返回null
> brpop tasks 5
1) "tasks"
2) "3"
> blpop tasks 5
1) "tasks"
2) "1"
> blpop tasks 5
1) "tasks"
2) "2"
> blpop tasks 5
(nil)
(5.08s)

集合、有序集合、哈希三条规则:

  1. 当我们向聚合(aggregate)数据类型添加一个元素,如果目标键不存在,添加元素前将创建一个空的聚合数
    据类型。
  2. 当我们从聚合数据类型删除一个元素,如果值为空,则键也会被销毁。
  3. 调用一个像 LLEN 的只读命令(返回列表的长度),或者一个写命令从空键删除元素,总是产生和操作一个持
    有空聚合类型值的键一样的结果。

规则1:

1
2
3
4
> del mylist
(integer) 1
> lpush mylist 1 2 3
(integer) 3

不能执行一个错误键类型的操作

1
2
3
4
5
6
> set foo bar
OK
> lpush foo 1 2 3
(error) WRONGTYPE Operation against a key holding the wrong kind of value
> type foo
string

规则2:

1
2
3
4
5
6
7
8
9
10
11
12
> lpush mylist 1 2 3
(integer) 3
> exists mylist
(integer) 1
> lpop mylist
"3"
> lpop mylist
"2"
> lpop mylist
"1"
> exists mylist
(integer) 0

当所有元素弹出后,键就不存在了

规则3:

1
2
3
4
5
6
> del mylist
(integer) 0
> llen mylist
(integer) 0
> lpop mylist
(nil)

哈希/散列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
> hmset user:1000 username csh birthday 1993 address GZ
OK
> hget user:1000 username
"csh"
> hget user:1000 birthday
"1993"
> hget user:1000 address
"GZ"
//获取所有键值对
> hgetall user:1000
1) "username"
2) "csh"
3) "birthday"
4) "1993"
5) "address"
6) "GZ"
//根据传入的多个键获取相应的值,如果没有该键值对,则返回(nil)
> hmget user:1000 username birthday no-such-field
1) "csh"
2) "1993"
3) (nil)
//自增键值对的值
> hincrby user:1000 birthday 10
(integer) 2003
> hincrby user:1000 birthday 10
(integer) 2013

Set操作

SADD 命令【添加元素到集合】

1
2
3
4
5
6
> sadd myset 1 2 3
(integer) 3
> smembers myset
1. 3
2. 1
3. 2

sismember 命令【判断元素是否在set中】

1
2
3
4
> sismember myset 3
(integer) 1
> sismember myset 30
(integer) 0

假设,我们想标记新闻。如果我们的 ID 为 1000 的新闻,被标签 1,2,5 和 77 标记,我们可以有一个这篇新闻
被关联标记 ID 的集合:

1
2
> sadd news:1000:tags 1 2 5 77
(integer) 4

然而有时候我们也想要一些反向的关系:被某个标签标记的所有文章:

1
2
3
4
5
6
7
8
> sadd tag:1:news 1000
(integer) 1
> sadd tag:2:news 1000
(integer) 1
> sadd tag:5:news 1000
(integer) 1
> sadd tag:77:news 1000
(integer) 1

smembers 命令【获取指定对象的标签】

1
2
3
4
5
> smembers news:1000:tags
1. 5
2. 1
3. 77
4. 2

sinter 命令【获取同时被1,2,10,27标记的新闻】

1
2
> sinter tag:1:news tag:2:news tag:10:news tag:27:news
... results here ...

扑克例子:
  抽取一个元素的命令是 SPOP,就方便为很多问题建模。
  例如,为了实现一个基于 web 的扑克游戏,你可以将你的一副牌表示为集合。假设我们使用一个字符前缀表示(C)lubs 梅花, (D)iamonds 方块,(H)earts 红心,(S)pades 黑桃。

1
2
3
4
5
> sadd deck C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 CJ CQ CK
D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 DJ DQ DK H1 H2 H3
H4 H5 H6 H7 H8 H9 H10 HJ HQ HK S1 S2 S3 S4 S5 S6
S7 S8 S9 S10 SJ SQ SK
(integer) 52

  现在我们为每位选手提供 5 张牌。SPOP 命令删除一个随机元素,返回给客户端,是这个场景下的最佳操作。
  然而,如果我们直接对这副牌调用,下一局我们需要再填充一副牌,这个可能不太理想。所以我们一开始要复制一下 deck 键的集合到 game:1:deck 键。
  这是通过使用 SUNIONSTORE 命令完成的,这个命令通常对多个集合执行交集,然后把结果存储在另一个集合中。而对单个集合求交集就是其自身,于是我可以这样拷贝我的这副牌:

1
2
> sunionstore game:1:deck deck
(integer) 52

现在我们准备好为第一个选手提供 5 张牌:

1
2
3
4
5
6
7
8
9
10
> spop game:1:deck
"C6"
> spop game:1:deck
"CQ"
> spop game:1:deck
"D1"
> spop game:1:deck
"CJ"
> spop game:1:deck
"SJ"

  只有一对 jack,不太理想……
  现在是时候介绍提供集合中元素数量的命令。这个在集合理论中称为集合的基数(cardinality,也称集合的势),所以相应的 Redis 命令称为 SCARD。

1
2
> scard game:1:deck
(integer) 47

数学计算式为:52 - 5 = 47。
  当你只需要获得随机元素而不需要从集合中删除,SRANDMEMBER 命令则适合你完成任务。它具有返回重复的和非重复的元素的能力。

有序集合(Sorted Sets)
按照如下规则排序:
• 如果 A 和 B 是拥有不同分数的元素,A.score > B.score,则 A > B。
• 如果 A 和 B 是有相同的分数的元素,如果按字典顺序 A 大于 B,则 A > B。A 和 B 不能相同,因为排序集合只能有唯一元素。

zadd命令【添加有序集合元素】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> zadd hackers 1940 "Alan Kay"
(integer) 1
> zadd hackers 1957 "Sophie Wilson"
(integer 1)
> zadd hackers 1953 "Richard Stallman"
(integer) 1
> zadd hackers 1949 "Anita Borg"
(integer) 1
> zadd hackers 1965 "Yukihiro Matsumoto"
(integer) 1
> zadd hackers 1914 "Hedy Lamarr"
(integer) 1
> zadd hackers 1916 "Claude Shannon"
(integer) 1
> zadd hackers 1969 "Linus Torvalds"
(integer) 1
> zadd hackers 1912 "Alan Turing"
(integer) 1

zrange命令【获取有序集合的一个范围】

1
2
3
4
5
6
7
8
9
10
> zrange hackers 0 -1
1) "Alan Turing"
2) "Hedy Lamarr"
3) "Claude Shannon"
4) "Alan Kay"
5) "Anita Borg"
6) "Richard Stallman"
7) "Sophie Wilson"
8) "Yukihiro Matsumoto"
9) "Linus Torvalds"

zrevrange命令【反顺序】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
> zrevrange hackers 0 -1
1) "Linus Torvalds"
2) "Yukihiro Matsumoto"
3) "Sophie Wilson"
4) "Richard Stallman"
5) "Anita Borg"
6) "Alan Kay"
7) "Claude Shannon"
8) "Hedy Lamarr"
9) "Alan Turing"
//添加withscores来显示分数
> zrange hackers 0 -1 withscores
1) "Alan Turing"
2) "1912"
3) "Hedy Lamarr"
4) "1914"
5) "Claude Shannon"
6) "1916"
7) "Alan Kay"
8) "1940"
9) "Anita Borg"
10) "1949"
11) "Richard Stallman"
12) "1953"
13) "Sophie Wilson"
14) "1957"
15) "Yukihiro Matsumoto"
16) "1965"
17) "Linus Torvalds"
18) "1969"

zrangebyscore / zremrangebyscore / zrank 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
//返回分数在负无穷到 1950 之间的所有元素(包括两个极端)
> zrangebyscore hackers -inf 1950
1) "Alan Turing"
2) "Hedy Lamarr"
3) "Claude Shannon"
4) "Alan Kay"
5) "Anita Borg"
//删除出生于1940到1960的人
> zremrangebyscore hackers 1940 1960
(integer) 4
//返回排行
> zrank hackers "Anita Borg"
(integer) 4

字典分数
如果集合中有相同的分数,允许按字典顺序获取范围

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> zadd hackers 0 "Alan Kay" 0 "Sophie Wilson" 0 "Richard Stallman" 0
"Anita Borg" 0 "Yukihiro Matsumoto" 0 "Hedy Lamarr" 0 "Claude Shannon"
0 "Linus Torvalds" 0 "Alan Turing"
//分数相同的按照字母字典顺序排
> zrange hackers 0 -1
1) "Alan Kay"
2) "Alan Turing"
3) "Anita Borg"
4) "Claude Shannon"
5) "Hedy Lamarr"
6) "Linus Torvalds"
7) "Richard Stallman"
8) "Sophie Wilson"
9) "Yukihiro Matsumoto"
//查询从B到P的元素
> zrangebylex hackers [B [P
1) "Claude Shannon"
2) "Hedy Lamarr"
3) "Linus Torvalds

位图(Bitmaps)

1
2
3
4
5
6
7
8
9
10
11
12
13
> setbit key 10 1
(integer) 1
> getbit key 10
(integer) 1
> getbit key 11
(integer) 0
> setbit key 0 1
(integer) 0
> setbit key 100 1
(integer) 0
//获取个数
> bitcount key
(integer) 2

回收策略(Eviction policies)
  当 maxmemory 限制到达的时候,Redis 将采取的准确行为是由 maxmemory-policy 配置指令配置的。
以下策略可用:
• noeviction:当到达内存限制时返回错误。当客户端尝试执行命令时会导致更多内存占用(大多数写命令,除
了 DEL 和一些例外)。
• allkeys-lru:回收最近最少使用(LRU)的键,为新数据腾出空间。
• volatile-lru:回收最近最少使用(LRU)的键,但是只回收有设置过期的键,为新数据腾出空间。
• allkeys-random:回收随机的键,为新数据腾出空间。
• volatile-random:回收随机的键,但是只回收有设置过期的键,为新数据腾出空间。
• volatile-ttl:回收有设置过期的键,尝试先回收离 TTL 最短时间的键,为新数据腾出空间。
  当没有满足前提条件的话,volatile-lru,volatile-random 和 volatile-ttl 策略就表现得和 noeviction 一样了。
  选择正确的回收策略是很重要的,取决于你的应用程序的访问模式,但是,你可以在程序运行时重新配置策略,使用 INFO 输出来监控缓存命中和错过的次数,以调优你的设置。
一般经验规则:
  • 如果你期待你的用户请求呈现幂律分布(power-law distribution),也就是,你期待一部分子集元素被访问得远比其他元素多,可以使用 allkeys-lru 策略。在你不确定时这是一个好的选择。
  • 如果你是循环周期的访问,所有的键被连续扫描,或者你期待请求正常分布(每个元素以相同的概率被访问),可以使用 allkeys-random 策略。
  • 如果你想能给 Redis 提供建议,通过使用你创建缓存对象的时候设置的 TTL 值,确定哪些对象应该被过期,你可以使用 volatile-ttl 策略。
  当你想使用单个实例来实现缓存和持久化一些键,allkeys-lru 和 volatile-random 策略会很有用。但是,通常最好是运行两个 Redis 实例来解决这个问题。
  另外值得注意的是,为键设置过期时间需要消耗内存,所以使用像 allkeys-lru 这样的策略会更高效,因为在内存压力下没有必要为键的回收设置过期时间。

回收过程 (Eviction process)
  理解回收的过程是这么运作的非常的重要:
   • 一个客户端运行一个新命令,添加了新数据。
   • Redis 检查内存使用情况,如果大于 maxmemory 限制,根据策略来回收键。
   • 一个新的命令被执行,如此等等。
  我们通过检查,然后回收键以返回到限制以下,来连续不断的穿越内存限制的边界。
  如果一个命令导致大量的内存被占用 (像一个很大的集合交集保存到一个新的键),一会功夫内存限制就会被这个明显的内存量所超越。

参考文章:
Redis 3.0 中文版

LVS的3种负载均衡技术的测试

发表于 2016-03-22   |   分类于 LVS   |     |   阅读次数

在测试之前安装ipvsadm
安装之前需要安装依赖:

1
yum install kernel-devel gcc openssl openssl-devel popt

到官网 【http://www.linuxvirtualserver.org 】下载ipvsadm时需要注意查看服务器内核版本

查询你的服务器内核版本:

1
rpm -q kernel-devel

根据服务器内核版本选择ipvsadm
下载后安装

1
2
3
4
5
tar -xvf ipvsadm-x.xx.tar.gz

cd ipvsadm-x.xx

make && make install

测试用的是3台CentOS7主机
node1 负载均衡服务器
node2 主机1
node3 主机2

第一种负载均衡:NAT
根据下图配置
NAT搭建图

在node1中创建脚本:lvs-dr-node1.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/bin/sh
#------mini-HOWTO-setup-LVS-NAT-director----------

#set ip_forward ON for vs-nat director (1 on, 0 off).
cat /proc/sys/net/ipv4/ip_forward
echo "1" >/proc/sys/net/ipv4/ip_forward

#director is gw for realservers
#turn OFF icmp redirects (1 on, 0 off)
echo "0" >/proc/sys/net/ipv4/conf/all/send_redirects
cat /proc/sys/net/ipv4/conf/all/send_redirects
echo "0" >/proc/sys/net/ipv4/conf/default/send_redirects
cat /proc/sys/net/ipv4/conf/default/send_redirects
echo "0" >/proc/sys/net/ipv4/conf/eno16777736/send_redirects
cat /proc/sys/net/ipv4/conf/eno16777736/send_redirects

#setup DIP
/sbin/ifconfig eno16777736 10.0.0.1 broadcast 10.0.0.255 netmask 255.255.255.0

#setup VIP
/sbin/ifconfig eno16777736:0 192.168.1.11 broadcast 192.168.1.255 netmask 255.255.255.0

#set default gateway
/sbin/route add default gw 192.168.1.1 netmask 0.0.0.0 metric 1

#clear ipvsadm tables
/sbin/ipvsadm -C

#install LVS services with ipvsadm
#add telnet to VIP with rr sheduling
/sbin/ipvsadm -A -t 192.168.1.11:80 -s rr

#first realserver
#forward telnet to realserver 10.0.0.2 using LVS-NAT (-m), with weight=1
/sbin/ipvsadm -a -t 192.168.1.11:80 -r 10.0.0.2:80 -m -w 1
#check that realserver is reachable from director
ping -c 1 10.0.0.2
#second realserver
#forward telnet to realserver 10.0.0.3 using LVS-NAT (-m), with weight=1
/sbin/ipvsadm -a -t 192.168.1.11:80 -r 10.0.0.3:80 -m -w 1
#checking if realserver is reachable from director
ping -c 1 10.0.0.3

#list ipvsadm table
/sbin/ipvsadm
#------mini-HOWTO-setup-LVS-NAT-director----------

在node2中创建脚本:lvs-dr-node2.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/sh
#---------mini-HOWTO-setup-LVS-NAT-realserver-------
#setup IP
/sbin/ifconfig eno16777736 10.0.0.2 broadcast 10.0.0.255 netmask 255.255.255.0
#installing default gw 10.0.0.1 for vs-nat'
/sbin/route add default gw 10.0.0.1
#show routing table
/bin/netstat -rn

#checking if DEFAULT_GW is reachable
ping -c 1 10.0.0.1

#looking for VIP on director from realserver
ping -c 1 10.0.0.3

#set_realserver_ip_forwarding to OFF (1 on, 0 off).
echo "0" >/proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward
#---------mini-HOWTO-setup-LVS-NAT-realserver-------

在node3中创建脚本:lvs-nat-node3.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/sh
#---------mini-HOWTO-setup-LVS-NAT-realserver-------
#setup IP
/sbin/ifconfig eno16777736 10.0.0.3 broadcast 10.0.0.255 netmask 255.255.255.0
#installing default gw 10.0.0.1 for vs-nat'
/sbin/route add default gw 10.0.0.1
#show routing table
/bin/netstat -rn

#checking if DEFAULT_GW is reachable
ping -c 1 10.0.0.1

#looking for VIP on director from realserver
ping -c 1 10.0.0.2

#set_realserver_ip_forwarding to OFF (1 on, 0 off).
echo "0" >/proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward
#---------mini-HOWTO-setup-LVS-NAT-realserver-------

分别给脚本附加执行权限

1
chmod -x lvs-nat-xxxxx.sh

分别运行3个脚本

1
./lvs-nat-xxxx.sh

NAT测试结果
NAT结果图

NAT脚本文件:
NAT脚本文件

第二种负载均衡:TUN
根据下图配置
TUN搭建图
在node1中创建脚本:lvs-tun-node1.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/bin/bash
#---------------mini-rc.lvs_dr-director------------------------
#set ip_forward OFF for lvs-dr director (1 on, 0 off)
#(there is no forwarding in the conventional sense for LVS-DR)
cat /proc/sys/net/ipv4/ip_forward
echo "0" >/proc/sys/net/ipv4/ip_forward

#director is not gw for realservers: leave icmp redirects on
echo 'setting icmp redirects (1 on, 0 off) '
echo "1" >/proc/sys/net/ipv4/conf/all/send_redirects
cat /proc/sys/net/ipv4/conf/all/send_redirects
echo "1" >/proc/sys/net/ipv4/conf/default/send_redirects
cat /proc/sys/net/ipv4/conf/default/send_redirects
echo "1" >/proc/sys/net/ipv4/conf/eno16777736/send_redirects
cat /proc/sys/net/ipv4/conf/eno16777736/send_redirects

#setup DIP
/sbin/ifconfig eno16777736 192.168.1.101 broadcast 192.168.1.255 netmask 255.255.255.0

#add ethernet device and routing for VIP 192.168.1.11
/sbin/ifconfig tunl0 192.168.1.11 broadcast 192.168.1.11 netmask 255.255.255.255
/sbin/route add -host 192.168.1.11 dev tunl0
#listing ifconfig info for VIP 192.168.1.11
/sbin/ifconfig tunl0

#check VIP 192.168.1.11 is reachable from self (director)
/bin/ping -c 1 192.168.1.11
#listing routing info for VIP 192.168.1.11
/bin/netstat -rn

#setup_ipvsadm_table
#clear ipvsadm table
/sbin/ipvsadm -C
#installing LVS services with ipvsadm
#add telnet to VIP with round robin scheduling
/sbin/ipvsadm -A -t 192.168.1.11:80 -s rr

#forward telnet to realserver using direct routing with weight 1
/sbin/ipvsadm -a -t 192.168.1.11:80 -r 192.168.1.102:80 -i -w 1
#check realserver reachable from director
ping -c 1 192.168.1.102

#forward telnet to realserver using direct routing with weight 1
/sbin/ipvsadm -a -t 192.168.1.11:80 -r 192.168.1.103:80 -i -w 1
#check realserver reachable from director
ping -c 1 192.168.1.103

#displaying ipvsadm settings
/sbin/ipvsadm

#not installing a default gw for LVS_TYPE vs-dr
#---------------mini-rc.lvs_dr-director------------------------

在node2中创建脚本:lvs-tun-node2.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
#----------mini-rc.lvs_dr-realserver------------------
#setup IP
/sbin/ifconfig eno16777736 192.168.1.103 broadcast 192.168.1.255 netmask 255.255.255.0
#installing default gw 192.168.1.1 for vs-dr
/sbin/route add default gw 192.168.1.1
#showing routing table
/bin/netstat -rn
#checking if DEFAULT_GW 192.168.1.1 is reachable
ping -c 1 192.168.1.1

#set_realserver_ip_forwarding to OFF (1 on, 0 off).
echo "0" >/proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward

#looking for DIP 192.168.1.101
ping -c 1 192.168.1.101

#looking for VIP (will be on director)
ping -c 1 192.168.1.11

#install_realserver_vip
/sbin/ifconfig tunl0 192.168.1.11 broadcast 192.168.1.11 netmask 0xffffffff up
#ifconfig output
/sbin/ifconfig tunl0
#installing route for VIP 192.168.1.11 on device tunl0
/sbin/route add -host 192.168.1.11 dev tunl0
#listing routing info for VIP 192.168.1.11
/bin/netstat -rn

#hiding interface tunl0, will not arp
echo "1" >/proc/sys/net/ipv4/conf/all/hidden
cat /proc/sys/net/ipv4/conf/all/hidden
echo "1" >/proc/sys/net/ipv4/conf/tunl0/hidden
cat /proc/sys/net/ipv4/conf/tunl0/hidden

#----------mini-rc.lvs_dr-realserver------------------

在node3中创建脚本:lvs-tun-node3.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
#----------mini-rc.lvs_dr-realserver------------------
#setup IP
/sbin/ifconfig eno16777736 192.168.1.102 broadcast 192.168.1.255 netmask 255.255.255.0
#installing default gw 192.168.1.1 for vs-dr
/sbin/route add default gw 192.168.1.1
#showing routing table
/bin/netstat -rn
#checking if DEFAULT_GW 192.168.1.1 is reachable
ping -c 1 192.168.1.1

#set_realserver_ip_forwarding to OFF (1 on, 0 off).
echo "0" >/proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward

#looking for DIP 192.168.1.101
ping -c 1 192.168.1.101

#looking for VIP (will be on director)
ping -c 1 192.168.1.11

#install_realserver_vip
/sbin/ifconfig tunl0 192.168.1.11 broadcast 192.168.1.11 netmask 0xffffffff up
#ifconfig output
/sbin/ifconfig tunl0
#installing route for VIP 192.168.1.11 on device tunl0
/sbin/route add -host 192.168.1.11 dev tunl0
#listing routing info for VIP 192.168.1.11
/bin/netstat -rn

#hiding interface tunl0, will not arp
echo "1" >/proc/sys/net/ipv4/conf/all/hidden
cat /proc/sys/net/ipv4/conf/all/hidden
echo "1" >/proc/sys/net/ipv4/conf/tunl0/hidden
cat /proc/sys/net/ipv4/conf/tunl0/hidden

#----------mini-rc.lvs_dr-realserver------------------

分别给脚本附加执行权限

1
chmod -x lvs-tun-xxxxx.sh

分别运行3个脚本

1
./lvs-tun-xxxx.sh

TUN测试结果
TUN结果图

TUN脚本文件:
TUN脚本文件

第三种负载均衡:DR
DR搭建图

在node1中创建脚本:lvs-dr-node1.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/bin/bash
#---------------mini-rc.lvs_dr-director------------------------
#set ip_forward OFF for lvs-dr director (1 on, 0 off)
#(there is no forwarding in the conventional sense for LVS-DR)
cat /proc/sys/net/ipv4/ip_forward
echo "0" >/proc/sys/net/ipv4/ip_forward

#director is not gw for realservers: leave icmp redirects on
echo 'setting icmp redirects (1 on, 0 off) '
echo "1" >/proc/sys/net/ipv4/conf/all/send_redirects
cat /proc/sys/net/ipv4/conf/all/send_redirects
echo "1" >/proc/sys/net/ipv4/conf/default/send_redirects
cat /proc/sys/net/ipv4/conf/default/send_redirects
echo "1" >/proc/sys/net/ipv4/conf/eno16777736/send_redirects
cat /proc/sys/net/ipv4/conf/eno16777736/send_redirects

#setup DIP
/sbin/ifconfig eno16777736 192.168.1.101 broadcast 192.168.1.255 netmask 255.255.255.0

#add ethernet device and routing for VIP 192.168.1.11
/sbin/ifconfig eno16777736:0 192.168.1.11 broadcast 192.168.1.11 netmask 255.255.255.255
/sbin/route add -host 192.168.1.11 dev eno16777736:0
#listing ifconfig info for VIP 192.168.1.11
/sbin/ifconfig eno16777736:0

#check VIP 192.168.1.11 is reachable from self (director)
/bin/ping -c 1 192.168.1.11
#listing routing info for VIP 192.168.1.11
/bin/netstat -rn

#setup_ipvsadm_table
#clear ipvsadm table
/sbin/ipvsadm -C
#installing LVS services with ipvsadm
#add telnet to VIP with round robin scheduling
/sbin/ipvsadm -A -t 192.168.1.11:80 -s rr

#forward telnet to realserver using direct routing with weight 1
/sbin/ipvsadm -a -t 192.168.1.11:80 -r 192.168.1.102:80 -g -w 1
#check realserver reachable from director
ping -c 1 192.168.1.102

#forward telnet to realserver using direct routing with weight 1
/sbin/ipvsadm -a -t 192.168.1.11:80 -r 192.168.1.103:80 -g -w 1
#check realserver reachable from director
ping -c 1 192.168.1.103

#displaying ipvsadm settings
/sbin/ipvsadm

#not installing a default gw for LVS_TYPE vs-dr
#---------------mini-rc.lvs_dr-director------------------------

在node2中创建脚本:lvs-dr-node2.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
#----------mini-rc.lvs_dr-realserver------------------
#setup IP
/sbin/ifconfig eno16777736 192.168.1.102 broadcast 192.168.1.255 netmask 255.255.255.0
#installing default gw 192.168.1.1 for vs-dr
/sbin/route add default gw 192.168.1.1
#showing routing table
/bin/netstat -rn
#checking if DEFAULT_GW 192.168.1.1 is reachable
ping -c 1 192.168.1.1

#set_realserver_ip_forwarding to OFF (1 on, 0 off).
echo "0" >/proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward

#looking for DIP 192.168.1.101
ping -c 1 192.168.1.101

#looking for VIP (will be on director)
ping -c 1 192.168.1.11

#install_realserver_vip
/sbin/ifconfig lo:0 192.168.1.11 broadcast 192.168.1.11 netmask 0xffffffff up
#ifconfig output
/sbin/ifconfig lo:0
#installing route for VIP 192.168.1.11 on device lo:0
/sbin/route add -host 192.168.1.11 dev lo:0
#listing routing info for VIP 192.168.1.11
/bin/netstat -rn

#hiding interface lo:0, will not arp
echo "1" >/proc/sys/net/ipv4/conf/all/hidden
cat /proc/sys/net/ipv4/conf/all/hidden
echo "1" >/proc/sys/net/ipv4/conf/lo/hidden
cat /proc/sys/net/ipv4/conf/lo/hidden

#----------mini-rc.lvs_dr-realserver------------------

在node3中创建脚本:lvs-dr-node3.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
#----------mini-rc.lvs_dr-realserver------------------
#setup IP
/sbin/ifconfig eno16777736 192.168.1.103 broadcast 192.168.1.255 netmask 255.255.255.0
#installing default gw 192.168.1.1 for vs-dr
/sbin/route add default gw 192.168.1.1
#showing routing table
/bin/netstat -rn
#checking if DEFAULT_GW 192.168.1.1 is reachable
ping -c 1 192.168.1.1

#set_realserver_ip_forwarding to OFF (1 on, 0 off).
echo "0" >/proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward

#looking for DIP 192.168.1.101
ping -c 1 192.168.1.101

#looking for VIP (will be on director)
ping -c 1 192.168.1.11

#install_realserver_vip
/sbin/ifconfig lo:0 192.168.1.11 broadcast 192.168.1.11 netmask 0xffffffff up
#ifconfig output
/sbin/ifconfig lo:0
#installing route for VIP 192.168.1.11 on device lo:0
/sbin/route add -host 192.168.1.11 dev lo:0
#listing routing info for VIP 192.168.1.11
/bin/netstat -rn

#hiding interface lo:0, will not arp
echo "1" >/proc/sys/net/ipv4/conf/all/hidden
cat /proc/sys/net/ipv4/conf/all/hidden
echo "1" >/proc/sys/net/ipv4/conf/lo/hidden
cat /proc/sys/net/ipv4/conf/lo/hidden

#----------mini-rc.lvs_dr-realserver------------------

分别给脚本附加执行权限

1
chmod -x lvs-dr-xxxxx.sh

分别运行3个脚本

1
./lvs-dr-xxxx.sh

DR测试结果

DR结果图

DR脚本文件:
TUN脚本文件

参考文章链接:
LVS配置教程

NAT、TUN、DR总结

发表于 2016-03-22   |   分类于 LVS   |     |   阅读次数

Virtual Server via NAT
  VS/NAT 的优点是服务器可以运行任何支持TCP/IP的操作系统,它只需要一个IP地址配置在调度器上,服务器组可以用私有的IP地址。缺点是它的伸缩能力有限, 当服务器结点数目升到20时,调度器本身有可能成为系统的新瓶颈,因为在VS/NAT中请求和响应报文都需要通过负载调度器。 我们在Pentium 166 处理器的主机上测得重写报文的平均延时为60us,性能更高的处理器上延时会短一些。假设TCP报文的平均长度为536 Bytes,则调度器的最大吞吐量为8.93 MBytes/s. 我们再假设每台服务器的吞吐量为800KBytes/s,这样一个调度器可以带动10台服务器。(注:这是很早以前测得的数据)
  基于 VS/NAT的的集群系统可以适合许多服务器的性能要求。如果负载调度器成为系统新的瓶颈,可以有三种方法解决这个问题:混合方法、VS/TUN和 VS/DR。在DNS混合集群系统中,有若干个VS/NAT负载调度器,每个负载调度器带自己的服务器集群,同时这些负载调度器又通过RR-DNS组成简 单的域名。但VS/TUN和VS/DR是提高系统吞吐量的更好方法。
  对于那些将IP地址或者端口号在报文数据中传送的网络服务,需要编写相应的应用模块来转换报文数据中的IP地址或者端口号。这会带来实现的工作量,同时应用模块检查报文的开销会降低系统的吞吐率。

Virtual Server via IP Tunneling
  在VS/TUN 的集群系统中,负载调度器只将请求调度到不同的后端服务器,后端服务器将应答的数据直接返回给用户。这样,负载调度器就可以处理大量的请求,它甚至可以调 度百台以上的服务器(同等规模的服务器),而它不会成为系统的瓶颈。即使负载调度器只有100Mbps的全双工网卡,整个系统的最大吞吐量可超过 1Gbps。所以,VS/TUN可以极大地增加负载调度器调度的服务器数量。VS/TUN调度器可以调度上百台服务器,而它本身不会成为系统的瓶颈,可以 用来构建高性能的超级服务器。
  VS/TUN技术对服务器有要求,即所有的服务器必须支持“IP Tunneling”或者“IP Encapsulation”协议。目前,VS/TUN的后端服务器主要运行Linux操作系统,我们没对其他操作系统进行测试。因为“IP Tunneling”正成为各个操作系统的标准协议,所以VS/TUN应该会适用运行其他操作系统的后端服务器。

Virtual Server via Direct Routing
  跟VS/TUN方法一样,VS/DR调度器只处理客户到服务器端的连接,响应数据可以直接从独立的网络路由返回给客户。这可以极大地提高LVS集群系统的伸缩性。
  跟VS/TUN相比,这种方法没有IP隧道的开销,但是要求负载调度器与实际服务器都有一块网卡连在同一物理网段上,服务器网络设备(或者设备别名)不作ARP响应,或者能将报文重定向(Redirect)到本地的Socket端口上。

三种方法的优缺点比较
三种IP负载均衡技术的优缺点归纳在下表中:

- VS/NAT VS/TUN VS/DR
Server any Tunneling Non-arp device
server network private LAN/WAN LAN
server number low (10~20) High (100) High (100)
server gateway load balancer own router own router

注: 以上三种方法所能支持最大服务器数目的估计是假设调度器使用100M网卡,调度器的硬件配置与后端服务器的硬件配置相同,而且是对一般Web服务。使用更 高的硬件配置(如千兆网卡和更快的处理器)作为调度器,调度器所能调度的服务器数量会相应增加。当应用不同时,服务器的数目也会相应地改变。所以,以上数 据估计主要是为三种方法的伸缩性进行量化比较。

参考文章链接
Linux服务器集群系统(三)

DR(Direct Routing)介绍

发表于 2016-03-22   |   分类于 LVS   |     |   阅读次数

通过直接路由实现虚拟服务器(VS/DR)
  跟VS/TUN 方法相同,VS/DR利用大多数Internet服务的非对称特点,负载调度器中只负责调度请求,而服务器直接将响应返回给客户,可以极大地提高整个集群 系统的吞吐量。该方法与IBM的NetDispatcher产品中使用的方法类似(其中服务器上的IP地址配置方法是相似的),但IBM的 NetDispatcher是非常昂贵的商品化产品,我们也不知道它内部所使用的机制,其中有些是IBM的专利。
  VS/DR的体系结构如下图所示:调度器和服务器组都必须在物理上有一个网卡通过不分断的局域网相连,如通过高速的交换机或者HUB相连。VIP地址为调度器和服务器组共享,调度 器配置的VIP地址是对外可见的,用于接收虚拟服务的请求报文;所有的服务器把VIP地址配置在各自的Non-ARP网络设备上,它对外面是不可见的,只是用于处理目标地址为VIP的网络请求。

DR的体系结构

  VS/DR 的工作流程如下图所示:它的连接调度和管理与VS/NAT和VS/TUN中的一样,它的报文转发方法又有不同,将报文直接路由给目标服务器。在VS/DR 中,调度器根据各个服务器的负载情况,动态地选择一台服务器,不修改也不封装IP报文,而是将数据帧的MAC地址改为选出服务器的MAC地址,再将修改后 的数据帧在与服务器组的局域网上发送。因为数据帧的MAC地址是选出的服务器,所以服务器肯定可以收到这个数据帧,从中可以获得该IP报文。当服务器发现 报文的目标地址VIP是在本地的网络设备上,服务器处理这个报文,然后根据路由表将响应报文直接返回给客户。

DR的工作流程

  在VS/DR中,根据缺省的TCP/IP协议栈处理,请求报文的目标地址为VIP,响应报文的源地址肯定也为VIP,所以响应报文不需要作任何修改,可以直接返回给客户,客户认为得到正常的服务,而不会知道是哪一台服务器处理的。
  VS/DR负载调度器跟VS/TUN一样只处于从客户到服务器的半连接中,按照半连接的TCP有限状态机进行状态迁移。

参考文章链接
Linux服务器集群系统(三)

TUN(IP Tunneling)介绍

发表于 2016-03-22   |   分类于 LVS   |     |   阅读次数

通过IP隧道实现虚拟服务器(VS/TUN)
  在VS/NAT 的集群系统中,请求和响应的数据报文都需要通过负载调度器,当真实服务器的数目在10台和20台之间时,负载调度器将成为整个集群系统的新瓶颈。大多数 Internet服务都有这样的特点:请求报文较短而响应报文往往包含大量的数据。如果能将请求和响应分开处理,即在负载调度器中只负责调度请求而响应直 接返回给客户,将极大地提高整个集群系统的吞吐量。
  IP隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,这可以使得目标为一个IP地址的数据报文能被封装和转发到另一个IP地址。IP隧道技 术亦称为IP封装技术(IP encapsulation)。IP隧道主要用于移动主机和虚拟私有网络(Virtual Private Network),在其中隧道都是静态建立的,隧道一端有一个IP地址,另一端也有唯一的IP地址。
  我们利用IP隧道技术将请求报文封装转 发给后端服务器,响应报文能从后端服务器直接返回给客户。但在这里,后端服务器有一组而非一个,所以我们不可能静态地建立一一对应的隧道,而是动态地选择 一台服务器,将请求报文封装和转发给选出的服务器。这样,我们可以利用IP隧道的原理将一组服务器上的网络服务组成在一个IP地址上的虚拟网络服务。 VS/TUN的体系结构如下图所示,各个服务器将VIP地址配置在自己的IP隧道设备上。

TUN的体系结构

  VS/TUN 的工作流程如下图所示:它的连接调度和管理与VS/NAT中的一样,只是它的报文转发方法不同。调度器根据各个服务器的负载情况,动态地选择一台服务器, 将请求报文封装在另一个IP报文中,再将封装后的IP报文转发给选出的服务器;服务器收到报文后,先将报文解封获得原来目标地址为VIP的报文,服务器发 现VIP地址被配置在本地的IP隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。

TUN的工作流程

  在这里需要指出,根据缺省的TCP/IP协议栈处理,请求报文的目标地址为VIP,响应报文的源地址肯定也为VIP,所以响应报文不需要作任何修改,可以直接返回给客户,客户认为得到正常的服务,而不会知道究竟是哪一台服务器处理的。

半连接的TCP有限状态机

参考文章链接
Linux服务器集群系统(三)

1…222324
LieBrother

LieBrother

当才华撑不起野心时,应该静下心来学习;当能力驾驭不了目标时,应该沉下心来历练。

120 日志
38 分类
138 标签
© 2016 - 2019 LieBrother
由 Hexo 强力驱动
主题 - NexT.Mist
本站访客数人次  |  本站总访问量次