刚过去的星期三(3-14)例行地主持了技能会议,核心正好是《UI层的设计形式——从Script、Code
Behind到MVC、MVP、MVVM》,是明天早上才定的,中午花了半钟头准备了下就开讲了。
目录
5.3. OOM相关:vm.overcommit_memory 4
5.4. /sys/kernel/mm/transparent_hugepage/enabled
4
11.3. jedis(Java cluster client) 11
11.4. r3c(C++ cluster client) 12
15.2. redis-trib.rb rebalance
14
明天来看了大家在为MVVM
knockout.js友(ji)好(lie)地调换,所以就打点下然后更增加地分享。
1. 前言
正文参考官方文档而成:http://redis.io/topics/cluster-tutorial。经测试,安装进度也适用于redis-3.2.0。
首要目标也不是为了争持,毕竟只是刚刚核心相近,原本的打算相当于五次技术分享并且记录下来。
2. 配置布署
基于官网介绍,安插6个redis节点,为3主3从。3台物理机每台都创立2个redis节点:
服务端口 |
IP地址 |
配置文件名 |
6379 |
192.168.0.251 |
redis-6379.conf |
6379 |
192.168.0.252 |
redis-6379.conf |
6379 |
192.168.0.253 |
redis-6379.conf |
6380 |
192.168.0.251 |
redis-6380.conf |
6380 |
192.168.0.252 |
redis-6380.conf |
6380 |
192.168.0.253 |
redis-6380.conf |
疑点:3台物理机,会不会主和从节点分布在同一个物理机上?
3. 目录结构
redis.conf为从https://raw.githubusercontent.com/antirez/redis/3.0/redis.conf下载的配备文件。redis-6379.conf和redis-6380.conf指定了劳务端口,两者均通过include复用(包括)了redis.conf。
本文将redis安装在/data/redis(每台机械完全相同,同一台机器上的八个节点对应同等的目录和文件,并提出将bin目录插手到环境变量PATH中,以简化后续的施用):
/data/redis |– bin | |– redis-benchmark | |– redis-check-aof | |– redis-check-dump | |– redis-cli | |– redis-sentinel -> redis-server | `– redis-server |– conf | |– redis-6379.conf | |– redis-6380.conf | `– redis.conf `– log
3 directories, 9 files |
那就是说大家就依照大概的历史进度将那一个概念举办分割:
4. 编译安装
开辟redis的Makefile文件,可以见见如下内容:
PREFIX?=/usr/local INSTALL_BIN=$(PREFIX)/bin INSTALL=install |
Makefile中的“?=”表示,要是该变量在此以前并未定义过,则赋值为/usr/local,否则怎么也不做。
设若不安装环境变量PREFIX或不改动Makefile中的值,则暗许安装到/usr/local/bin目录下。提出不用采纳暗中认同配置,而是指虞诩装目录,如/data/redis-3.0.5:
$ make $ make install PREFIX=/data/redis-3.0.5 $ ln -s /data/redis-3.0.5 /data/redis $ mkdir /data/redis/conf $ mkdir /data/redis/log $ mkdir /data/redis/data |
- Script
- Code Blocks、Code Behind
- MVC、MVP、MVVM
5. 修改系统参数
咱俩知晓的是有血有肉的历史发生顺序并不如上,因为思想都以形似的,比如MVC很早很已经出现了,解释型语言到现在基本上也有广大支行而且在网络时期大行其道。
5.1. 修改最大可打开文件数
修改文件/etc/security/limits.conf,参加以下两行:
* soft nofile 102400 * hard nofile 102400
# End of file |
里面102400为一个经过最大可以打开的公文个数,当与RedisServer的连接数多时,须要设定为方便的值。
修改后,需求重新登录才会立见成效,若是是crontab,则必要重启crontab,如:service crond restart,有些平台恐怕是service cron restart。
但我要说的是:无须在意那一个细节!
5.2. TCP监听队列大小
即TCP listen的backlog大小,“/proc/sys/net/core/somaxconn”的暗许值一般较小如128,必要修改大一些,比如改成32767。马上生效还能动用命令:sysctl -w net.core.somaxconn=32767。
要想永远生效,须要在文书/etc/sysctl.conf中追加一行:net.core.somaxconn = 32767,然后执行命令“sysctl -p”以生效。
当然了,那是笑话,我的意趣是,这一个剧情本人懒得应该在其余独立的主旨探究,篇幅也有数。
5.3. OOM相关:vm.overcommit_memory
如果“/proc/sys/vm/overcommit_memory”的值为0,则会表示开启了OOM。可以安装为1关闭OOM,设置格局请参考net.core.somaxconn完毕。
5.4. /sys/kernel/mm/transparent_hugepage/enabled
默许值为“[always] madvise never”,提出安装为never,以打开内核的“Transparent Huge Pages (THP)”脾气,设置后redis进程要求重启。为了永恒生效,请将“echo never > /sys/kernel/mm/transparent_hugepage/enabled”加入到文件/etc/rc.local中。
6. 配置redis
从https://raw.githubusercontent.com/antirez/redis/3.0/redis.conf下载配置文件(也可间接复制源代码包中的redis.conf,然后在它的根基上展开改动),在那几个基础上,进行如下表所示的改动(配置文件名redis-6379.conf中的6379指出安装为实在利用的端口号):
配置项
值
计划文件
说明
port
6379
redis-6379.conf
客户端连接端口,并且总有一个恰恰超越10000的端口,那个大的端口用于主从复制和集群内部通讯。
cluster-config-file
nodes-6379.conf
pidfile
/var/run/redis-6379.pid
除非当daemonize值为yes时,才有含义;并且这些需求对目录/var/run有写权限,否则可以考虑设置为/tmp/redis-6379.pid。
dir
/data/redis/data/6379
dbfilename
dump-6379.rdb
身处dir指定的目录下
appendfilename
“appendonly-6379.aof”
logfile
/data/redis/log/redis-6379.log
日志文件,包罗目录和文书名
loglevel
verbose
日志级别
port
6380
redis-6380.conf
cluster-config-file
nodes-6380.conf
pidfile
/var/run/redis-6380.pid
dir
/data/redis/data/6380
AOF和RDB文件存放目录
dbfilename
dump-6380.rdb
RDB文件名
appendfilename
appendonly-6380.aof
AOF文件名
logfile
/data/redis/log/redis-6380.log
loglevel
verbose
日记级别
cluster-enabled
yes
redis.conf
表示以集群形式运行,为no表示以非集群格局运行
cluster-node-timeout
3000
单位为毫秒:
repl-ping-slave-period+
(cluster-node-timeout*
cluster-slave-validity-factor)
cluster-slave-validity-factor
0
如果要最大的可用性,值设置为0
repl-ping-slave-period
1
slave ping master的时间距离,单位为秒
repl-timeout
10
复制超时,单位为秒,须高于repl-ping-slave-period的值
slave-read-only
yes
slave是还是不是只读
slave-serve-stale-data
yes
当slave与master断开连接,slave是还是不是持续提供劳务
slave-priority
100
slave权重值,当master挂掉,唯有权重最大的slave接替master
appendonly
yes
当同时写AOF或RDB,则redis启动时只会加载AOF,AOF包蕴了全量数据
daemonize
yes
有关配置项pidfile
protected-mode
no
3.2.0新增的安排项,暗中同意值为yes,限制从别的机器登录Redis server,而不得不从127.0.0.1登录。为力保redis-trib.rb工具的正规运作,必要安装为no,已毕后方可改回yes,但老是使用redis-trib.rb都亟需改回为no。要想从非127.0.0.1造访也亟需改为no。
tcp-backlog
32767
取值无法超过系统的/proc/sys/net/core/somaxconn
auto-aof-rewrite-percentage
100
安装自动rewite AOF文件(手工rewrite只须求调用命令BGREWRITEAOF)
auto-aof-rewrite-min-size
64mb
触发rewrite的AOF文件大小,唯有超越此大小时才会触发rewrite
no-appendfsync-on-rewrite
yes
子进程在做rewrite时,主进度不调用fsync(由基础专断认同调度)
cluster-require-full-coverage
no
为no表示有slots不可服务时其余slots依旧此起彼伏服务
Script
那边脚本的情致不是指及时是用脚本开发,而是像写脚本一样付出。它们都有一个脾性:功效单一、管理单一、入口单一。
咱俩最早的顺序是汇编,当时的码农的劳作是专职,工作内容是编制一套寿命相当长的机械控制指令,有些甚至是命令,比如至今依旧保留的Command(亮点自寻):
到后来电脑被用来科学总括等,必要促进了须求更高的支付成效,所以大家有了高档语言。
相当时候码农其实多是物物理学家,程序的效果很粗略,就是举行一些数学总结,类似今天ICPC的局地算法难题,比如Hello
World:
main()
{
printf("hello,world\n");
}
那儿,程序还足以被总结为输入到输出的进度,我们还是能去讲讲冯诺依曼模型。
在那个时代,开发是指编写机器指令,甚至都不配用“开发”那个词来描述那项工作。
7. 启动redis实例
签到3台物理机,启动八个redis实例(启动在此以前,须要创建好布局中的各目录):
1) redis-server redis-6379.conf
2) redis-server redis-6380.conf
可以写一个开行脚本start-redis-cluster.sh:
#!/bin/sh
REDIS_HOME=/data/redis $REDIS_HOME/bin/redis-server $REDIS_HOME/conf/redis-6379.conf $REDIS_HOME/bin/redis-server $REDIS_HOME/conf/redis-6380.conf |
软件、UI和Markup Language
在格外时期讲UI等于放屁,根本不设有那种概念。但全赖大家有神器——穆尔定律。
但我个人认为Moore定律是不足以让一个敲命令行的一世在几十年间转变成那种种种框架技术架构实践格局的年代,真正促进统计机形成自有的工程学种类的是还有不相同事物就是:
- 人的力量并从未变强,至少没有在同级数下变强。
- 人类自然会因地制宜
因为人的力量并不曾“跟上”机器,所以才会冒出各类方式、方法、工具等等来补足人的欠缺,以最大地透支机器品质。就好像自家后天在闪存无聊时忽然想到的一句: 架构是对合理不足的投降,规范是对不合理不足的折衷。
当我们要求机械做的作业多了起来,大家就无法在一个芯片上缓解所有业务,所以才会有冯诺依曼模型、计算机架构,不可以用一台机械化解,所以才要互连网、分布式、云总计。
相同,随着电脑的腾飞,要做的事情多了,就应运而生了软件的定义。当“开发”正式化,大家必要的软件就变得:意义紊乱、管理统一、多入口。
诚然转移的不是在理本质,而是要求。似乎那里说的“软件入口”在创设上大家仍然唯有一个,原理上平素都唯有一个起动程序、一个开端代码片段。但“软件的入口”,已经从代表Main函数变成了代表初始UI,用户已经从代表专业人士变成了代表一般消费者,先有软件的要求,才有软件的定义,而需即使在转变的。
一个软件要求比登时多多少个数据级的代码:
- 创建上大家不只怕做一个能显得所有代码的显示器
- 主观上大家不可能在超高速轮转中看清所有代码
于是大家须求添加索引、用多个文件社团代码。
机器的开拓进取和软件的急需扩展和细化,大家开始产出了用户界面(User
Interface)的概念和最符合用来界面的言语——标记语言(马克up
Language)。当然,ML不是为UI而生的,它只是可怜适合UI,所以才和UI坠入爱河。
因为有了更高UI的必要,所以代码才正式被不同为描述做哪些(业务逻辑)和有啥(UI)的两有的,因为大家付出时不能在三种沉思方式下同时工作,开发时的脑髓是单线程的。大家所观察的还要拓展UI和逻辑开发只然而是大家学会了在二种格局下快捷切换,看起来像同时展开,而不是实在的还要拓展。同样的情况也暴发在不一样的代码片段的付出中。
分歧的景象除了UI,还暴发在全部,比如数据操作、UI的靶子和体制分离,大家依旧持续从UI讲下去吧。
8. 开立和开行redis cluster前的准备工作
上一步启动的redis只是单机版本,在起步redis cluster此前,要求做到如下一些凭借的设置。在此之后,才可以成立和开行redis cluster。
Code Block和Code Behind(其实还有Code Inside,比如onclick=”javascript:alert(‘哎呀我*’)”)
UI和逻辑分开了两种语言来写,可是它们也要放在同一个连串中,因为它们原来就是要一同坐班的。尽管是分离,也亟需不停,因为那是它们本来要缓解的难点。
那会儿我们出现的(寻常的)化解方案就是Code Block和Code
Behind。纵然从岁月上似乎Code Block比Code
Behind要早,有种感觉就是越新越好,但精神上它们正交替地发展着,因为何人也无法化解UI和逻辑代码不一致后的一个经济学难题——UI和逻辑是一起的,可是它们却不是一路的。
Code
Block能很好地处理UI和逻辑间在同步的涉及,你在同一个地方可以同时有限辅助UI和逻辑:
1 @model GM.OA.Finance2.Web.Models.FinancialBase.CurrencyModel
2 @{
3 ViewBag.Title = "EditCurrencyDrawer";
4 Layout = "~/Views/Shared/_DrawerLayout.cshtml";
5 }
6
7 @section styles {
8 <link href="/Content/base/table-form.css" rel="stylesheet" />
9 <link href="/Content/base/drawer.bigtitle.css" rel="stylesheet" />
10 }
<a href="#" class="addcurrency oa-btn" oa-style="green">添加新币别</a>
<script type="text/javascript">
$(document).ready(function () {
$('.addcurrency').click(function () {
$.oa.drawer.openUrl('AddCurrencyDrawer/', 'addcurrency', {
width: 300
});
});
});
</script>
Code
Behind能很好地拍卖UI和逻辑各自分离的关联,你可以让UI和逻辑各自做好各自的政工:
<asp:Button ID="RemoveSelectedCurrency_Button" runat="server" Text="删除选中币别" OnClick="RemoveSelectedCurrency_Button_Click" />
<asp:Button ID="RemoveAllCurrencies_Button" runat="server" Text="删除所有币别" OnClick="RemoveAllCurrencies_Button_Click" />
1 protected void RemoveSelectedCurrency_Button_Click(object sender, EventArgs e)
2 {
3 var currencyId = Currencies_ListBox.SelectedItem.Value;
4 currencyManager.Remove(currencyId);
5 }
6
7 protected void RemoveAllCurrencies_Button_Click(object sender, EventArgs e)
8 {
9 currencyManager.RemoveAll();
10 }
因为存在三种完毕格局,所以就存在了比较,因为存在了对待,所以就存在了龃龉。如同Java和.NET、PHP和.NET、WebForm和MVC、Mac
OS和Windows、iOS和Android、腾讯和具有其余互连网商家,等等。
标题不在哪个更好,而是大家要缓解哪些难题。当然,那听(ben)着(lai)像(jiu)是谦虚谨慎话了。
真正在UI和逻辑分歧后拉动的实质难题是:
- 是按逻辑和UI划分地管理,依然按单界面的作业进行私分地保管
至少UI和逻辑刚不相同的一世,在软件上,大家还认为相同项工作是依据同一个UI的一系列操作完结的。
在Moore定律还持续发挥功能的时候,计算机世界如故飞快发展,所以经常大家还在为同一东西争持、思考、辩证的时候,它曾经爆发了衍生和变化了,不变的只是大家要缓解的难题。
8.1. 安装ruby
设置命令:yum install ruby
设置进度中,如提示“[y/d/N]”,请选“y”然后回车。
查看版本:
$ ruby –version ruby 2.0.0p353 (2013-11-22) [x86_64-Linux] |
也足以从Ruby官网https://www.ruby-lang.org下载安装包(如ruby-2.3.1.tar.gz)来安装Ruby。截止2016/5/13,Ruby的风靡稳定版本为Ruby 2.3.1。
事务,以及界面、数据、事件、业务
在头里说到过了,当须要变得高大,化解方案也会变得高大;当化解方案变得巨大,就会晤世细分;当现身细分,就会油但是生按哪个种类艺术管理的题材。
软件从拍卖一件工作发展到了要拍卖许多事情,各业务间有隐含、顺序、主次等等的关系,变得更为复杂。因为数量与逻辑庞大了,所以数据与逻辑就分开了,然后事件和事情分别了。
它们的涉及一度在大家还理得清前边频频前进而变得进一步难理得清,但在一个岁月点上,它们UI的园地几乎差距成那几个原子:
- 界面
- 数据
- 事件
- 业务
您要细化的话会有更加多杂乱的底细,但相信如此写的话争议性相比小。
当一个题材应运而生三回的时候它是一个难点,当一个难点应运而生了重重次的时候它会变成历史,当一个标题将会出现过很多次的时候,它将必要一个斐然的定义和搞定方案。
其中,数据的换代和界面的更新这一新鲜事件的题目被加大了无数倍,因为它出现了众多次。
8.2. 安装rubygems
安装命令:yum install rubygems
只要不使用yum安装,也足以手动安装RubyGems,RubyGems是一个Ruby包管理框架,它的下载网址:https://rubygems.org/pages/download。
例如下载安装包rubygems-2.6.4.zip后解压,然后进入解压生成的目录,里面有个setup.rb文件,以root用户执行:ruby setup.rb安装RubyGems。
Model-View-Controller
在ASP还在奋发的时候WebForm突然到来,正如WebForm还在斗争的时候MVC突然来到。当然,自己那里讲的MVC仍旧最原始的MVC,因为MVC在我们还在顶牛的时候已经发展了无数例外分支了。
有几许信任大家同意的就是,大家明日啄磨争持的MVC、MVP、MVVM、Code
Behind等等都源自于职能分歧和安插的思辨与目的,MVC不是它们的启幕,可是一个很好的开首。
信任MVC的模子大家很精晓,也很不难找到,我们那里用一下某百科的图:
俺们得以看看的是,界面被分到了View,数据分到了载体Model上由Model“教导”,业务集中在Controller中,而拉动工作的轩然大波由用户与View交互,通过View向Controller发动。
理所当然,已毕由很各样,每一种细节上都有不相同,所以我才只讲也只好讲大概的MVC。MVC的里边一个弱点便是绝非鲜明的概念,所以差其他落成(比如Struts和ASP.NET
MVC)细节上都是不雷同的。
大家须求驾驭的是,MVC并不是像上边所说的部分作业那样是一种“必然的”结果,它是一文山会海必然结果难点中的一种缓解方案,而且是不健全的搞定方案。大家本着推理去到一个地点很简单犯的一个错误就是认为路唯有这一条而忽略其余或者(估量这也是引致众多揪斗的来头)。其它,我们在议论一件事物不周详的时候是有一个田地的,所以请不要像“我说它色彩单一,然后您把它涂成彩色后证实自己是错的”。
MVC的相似流程是那样的:View(界面)触发事件–》Controller(业务)处理了作业,然后触发了数额更新–》不明白什么人更新了Model的多寡–》Model(带着数量)回到了View–》View更新数据
此间也不多再陈述MVC的法则、实践等等,因为那就太长篇大论了。
8.3. 安装redis-3.0.0.gem
安装命令:gem install -l redis-3.0.0.gem
安装从前,要求先下载好redis-3.0.0.gem。
redis-3.0.0.gem官网:https://rubygems.org/gems/redis/versions/3.0.0
redis-3.0.0.gem下载网址:https://rubygems.org/downloads/redis-3.0.0.gem
redis-3.3.0.gem官网:https://rubygems.org/gems/redis/versions/3.3.0
Model-View-Presenter和一部分衍生
像我们事先推理的,差别是一种要求的必然结果,但却从未个一个规定的结果,比如Code
Behind和Code Block的题目等等。
MVC顺着须求把UI相关的干活分歧成了三份,那一点通过实践证明无可厚非。不过它们的三角关系却被有些人认为带来了有的难点,只怕应当说他们有“更好的”化解方案。
在唯有Code Behind和Code
Block的非常时候维护是很直接的,不是在相同段代码内化解就是在同一个事关的轩然大波上缓解。三角关系的题材就是维护难题。在MVC,当您有转变的时候你需求同时敬重多个目的和多少个互相,那分明让工作复杂化了。
大家以前说到,随着穆尔定律,软件的必要持续地生成和变得高大。随着要求变得高大的时候,须要变化也变得频仍,那是一个面世了许多次之后也将会出现许多的洋洋次的一个题目,所以它须要一个缓解方案,哪怕它不必然能被化解。
为了搞定急需转变,从《人月典故》到高速到DDD,它不是我们早就缓解了的题材,而是我们正在化解的标题。放在UI的形式和MVC上来讲,就是优化仍旧替代MVC方式,其中之一就是Model-View-Presenter(MVP)格局。
咱俩先看看八个MVP情势的图:
(图一)
(图二)
两幅图是例外的,不过对MVC的一字不苟的思索却是一样的:隔断的View和Model的关系,让View只和Presenter(原Controller)交互,裁减在必要变化中要求爱抚的目的的数据。
那种格局很吻合大家的梦想,因为大家赞成于:
- 用更低的费用化解难题
- 用更易于领会的法子搞定问题
洋洋时候并不是一种格局不佳,而是因为人不大概举行,比如不易于了然,大家就会选拔不难通晓的艺术。电脑倚重穆尔定律用数据的增加来化解难点,而人是用艺术的更改来解决难点的。同样因为客观原因咱们不擅长维护五个对象和五个对象时期的关联,所以大家转移了,只怕说简化了那种方法。
MVP定义了Presenter和View之间的接口,让有些方可根据已有些接口协议去分别分别独立开发,以此去化解界面须求变化频仍的标题。上边两图都有接口,可是接口的贯彻和利用细节不一样,可是思想上是一样的。
在那边要涉及的是,事实上,要求转变最频仍的并不一定是最相仿用户的界面,但基本可以规定的是,最相近用户的界面是因为必要转变而急需最频仍更改的。当然,倘诺View如果是API而不是UI,那就另说了。
再有局地用来“化解”MVC那项缺点的比如说有:ASP.NET
MVC的ViewBag,Cocoa的delegate。它们都为了简化数据更新的标题而留存,包罗MVVM。
9. redis-trib.rb
redis-trib.rb是redis官方提供的redis cluster管理工具,使用ruby已毕。
Model-View-ViewModel
先直接看看Model-View-ViewModel(MVVM)的图:
从图上看是比MVP不难了,更毫不说MVC了。个人不觉得MVVM是从MVP进化而来,我只以为这是在MVP之后出现的一种“更好的”UI方式化解方案,可是用MVP来与之相比较比较容易表达难点。
ViewModel几乎上就是MVP的Presenter和MVC的Controller了,而View和ViewModel间没有了MVP的界面接口,而是直接互动,用多少“绑定”的款式让数据更新的事件不需求开发人士手动去编写特殊用例,而是自行地双向同步。数据绑定你可以认为是Observer格局只怕是Publish/Subscribe格局,原理都是为了用一种统一的汇聚的章程贯彻多次须要被完成的多少更新难点。
比起MVP,MVVM不仅简化了作业与界面的正视关系,还优化了数额频仍更新的解决方案,甚至足以说提供了一种有效的缓解格局。
由来,大家能驾驭为何许四人觉着MVVM是最好的一种形式,没有之一。但实则,MVVM也是凭借于大家至今所讲的“特有的境地”。
理所当然,最优雅的也是率先个能作代表的举行就是Windows Presentation
Foundation(WPF)了。
10. 成立和启动redis集群
Web
如上,大家在方式衍生和变化的测算基本上都仍然依照桌面软件的,不过千古十年却是互连网的一时。实际上多数让大家争议的并不是在桌面领域最合适的是丰硕,而是在Web领域的格局难点,约等于在B/S场景下的题目。
当软件离开单机,去到互联网的时候,因为场景变了,所以本来的解决方案也变了,不过需要照旧是不变的。我们依然要化解的标题是用户交互与数码更新的难题,还有爱抚等等的题材。
实地景变到Web的时候,我们发现MVVM用来做服务端是非凡不适用的,至少以后是不适用的。而MVP你提都不要提。为什么吧?因为:
- 互连网资源开支过高
- 开发用度过高
问我们一个题材,当一个网页的数目更新后,你希望更新用户看到的数额,你会如何是好?
相似意况下,你会:
window.location.reload();
纵使你不这么做,用户也会:
F5
如同此前说的,我们会接纳更直接的章程缓解难点。直接刷新页面的来由是因为这么更直接,更便于化解数据更新的题材。
有的是时候您不会愿意为了一个数目更新写一个AJAX,更别说那么些AJAX要牵动Loading、事件顺序处理、互连网难点、很是处理等等,那就是开发费用过高。
另一个网络花费过高就更便于解释了,即便宽带是骨干包月的,但也不带这么用的,何况还有移动用户。更关键的因由是,在地点软件,更新数据是一个引用问题,而在互联网采纳上,那是一个传输难题。传输费用远高于引用费用,引用之上顶多是在地点内存中再进行一回内存拷贝。
本条时候,大家会更倾向于用MVC形式,因为在Web层面,大家更倾向于四遍性更新数据。
10.1. 复制redis-trib.rb
将redis源代码的src目录下的集群管理程序redis-trib.rb复制到/data/redis/bin目录,并将bin目录出席到环境变量PATH中,以简化后续的操作。
redis-trib.rb用法(不带任何参数执行redis-trib.rb即突显用法):
$ ./redis-trib.rb Usage: redis-trib <command> <options> <arguments …>
rebalance host:port –auto-weights –timeout <arg> –pipeline <arg> –use-empty-masters –weight <arg> –threshold <arg> –simulate add-node new_host:new_port existing_host:existing_port –slave –master-id <arg> reshard host:port –timeout <arg> –pipeline <arg> –yes –slots <arg> –to <arg> –from <arg> check host:port set-timeout host:port milliseconds call host:port command arg arg .. arg fix host:port –timeout <arg> info host:port create host1:port1 … hostN:portN –replicas <arg> import host:port –replace –copy –from <arg> help (show this help) del-node host:port node_id
For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster. |
Web的MVVM
负有难题都不是题材,即使有标题也要化解难点。
为啥这些标题下突然冒出那般一句话?我想说的是,须要照旧是不变的,是牵动发展的原动力。
再有自身后面说过,当我们谈论恐怕争论一个难题的时候,难题的靶子已经暴发变动了,而且这一次是在大家谈论这么些标题以前早已发出改变了。
网络资源费用持续下跌,相信已经不须求多提及。穆尔定律和相近的部分法则正在发挥着它采取的效果,网络带宽越来越高、相应速度越来越快。
比方传输因为相对花费下落而造成数据传输的本钱低于开发人士拒绝客户的老本,那么它就会被完毕而不是被拒绝。
其余还有某些就是因为技术的前行,技术的资源持续被更大范围地压榨,需要也持续地抓实,那么须要一直会增强超越相对不变的开发用度的。比如jQuery的产出缓解了很多难题,大家明天越来越多地去行使AJAX,哪怕很大一部分照样是为着缓解互连网资源缺少的题材;大家会用更多的体裁代码而用了针锋相对更少的图样;大家不再那么依赖Flash一类的矢量图化解方案而直接摄像录像。
起码上一节我们说到的多少个导致大家接纳MVC的题材都正在被化解,所以我们有理由相信今后Web不仅仅必要MVC,可能会须求MVVM或其它化解方案。至少我们能领略简单明白为啥前端会产出局地MVVM的框架,比如先驱knockout.js和AngularJs。那些框架自身的三六九等就不作商量了,因为大家切磋的是格局。
在Web上,MVVM的对照对象就不是MVC,而是Code Block。
数码立马更新的需要在增加,但不至于有高达自然要用MVVM这一等级的大侠上的格局,实际上借使你要创新一个数据,你如故会使用:
$('.notice').html('发送成功!');
因为……大家照例会选择更直白的法门缓解难点……
实质上,以往Web
MVVM主要并不是用在了Web或许Wap上,而是移动App上。依照前面的说教,只只怕是:
- HTML+JS比原生在一部分现象上更适合Native
- 在移动App上比Web上更合乎采用MVVM
尽管是Native开发,实际上iOS的开支上也是用接近的多少绑定的点子的。那里也不追究了,毕竟自个儿也不算懂iOS。
要说的是,在Web
MVVM大概Web的情势上,约等于Web的富应用上,以往还只是是个最初由膨胀的须求牵动的级差。重点的不是技术会怎么走,而是须求和客观条件会怎么走。
想必Webform会因为迅速开发而神气第二春,它的AJAX的方式也非常满意于简单开发,但似乎大家须求的不是GUI式的网页。
10.2. 创建redis cluster
创建命令(3主3从):
redis-trib.rb create –replicas 1 192.168.0.251:6379 192.168.0.252:6379 192.168.0.253:6379 192.168.0.251:6380 192.168.0.252:6380 192.168.0.253:6380 |
Ø 参数表达:
1) create
意味着创制一个redis cluster集群。
2) –replicas 1
代表为集群中的逐个主节点指定一个从节点,即一比一的复制。\
运行进度中,会有个提醒,输入yes回车即可。从显示屏输出,可以很不难地看出什么是主(master)节点,哪些是从(slave)节点:
>>> Creating cluster Connecting to node 192.168.0.251:6379: OK /usr/local/share/gems/gems/redis-3.0.0/lib/redis.rb:182: warning: wrong element type nil at 0 (expected array) /usr/local/share/gems/gems/redis-3.0.0/lib/redis.rb:182: warning: ignoring wrong elements is deprecated, remove them explicitly /usr/local/share/gems/gems/redis-3.0.0/lib/redis.rb:182: warning: this causes ArgumentError in the next release >>> Performing hash slots allocation on 6 nodes… Using 3 masters: 192.168.0.251:6379 192.168.0.252:6379 192.168.0.253:6379 Adding replica 192.168.0.252:6380 to 192.168.0.251:6379 Adding replica 192.168.0.251:6380 to 192.168.0.252:6379 Adding replica 192.168.0.253:6380 to 192.168.0.253:6379 M: 150f77d1000003811fb3c38c3768526a0b25ec31 192.168.0.251:6379 slots:0-5460 (5461 slots) master M: de461d3337b17d2119b79024d57d8b119e7320a6 192.168.0.252:6379 slots:5461-10922 (5462 slots) master M: faf50658fb7b0bae64cee5371da782e0f4919eee 192.168.0.253:6379 slots:10923-16383 (5461 slots) master S: c567db02cc40eebf577f71f703214dd2f4f26dfb 192.168.0.251:6380 replicates de461d3337b17d2119b79024d57d8b119e7320a6 S: 284f8196b250ad9ac272316db84a07bebf661ab7 192.168.0.252:6380 replicates 150f77d1000003811fb3c38c3768526a0b25ec31 S: 39fdef9fd5778dc94d8add819789d7d73ca06899 192.168.0.253:6380 replicates faf50658fb7b0bae64cee5371da782e0f4919eee Can I set the above configuration? (type ‘yes’ to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join…. >>> Performing Cluster Check (using node 192.168.0.251:6379) M: 150f77d1000003811fb3c38c3768526a0b25ec31 192.168.0.251:6379 slots:0-5460 (5461 slots) master M: de461d3337b17d2119b79024d57d8b119e7320a6 192.168.0.252:6379 slots:5461-10922 (5462 slots) master M: faf50658fb7b0bae64cee5371da782e0f4919eee 192.168.0.253:6379 slots:10923-16383 (5461 slots) master M: c567db02cc40eebf577f71f703214dd2f4f26dfb 192.168.0.251:6380 slots: (0 slots) master replicates de461d3337b17d2119b79024d57d8b119e7320a6 M: 284f8196b250ad9ac272316db84a07bebf661ab7 192.168.0.252:6380 slots: (0 slots) master replicates 150f77d1000003811fb3c38c3768526a0b25ec31 M: 39fdef9fd5778dc94d8add819789d7d73ca06899 192.168.0.253:6380 slots: (0 slots) master replicates faf50658fb7b0bae64cee5371da782e0f4919eee [OK] All nodes agree about slots configuration. >>> Check for open slots… >>> Check slots coverage… [OK] All 16384 slots covered. |
结尾语
咱俩不肯定必要MVVM,但大家必定须要更有力的措施去解决持续膨胀的Web须要。
大家得以预言的是:
- 会有更强有力的浏览器
- 会有更强硬的JavaScript或许框架
- 会有更为切合的方式
除外客气话的有的,我或然想说,在区其余急需下实际有最适合的搞定方案,一般性让大家纠结的不是因为哪个解决方案更好,而是大家看出的标准不够多。
编译语言当然比解释语言成效高,但考虑到支付和保养资产,JavaScript等平素会流行,比如Node.JS、Python;.NET和微软自然很有力,移植.NET到其余平台也很简单,但微软是家有谈得来商业格局和要纯利的商店;当然有些实践和技能更好,但其他开发人士会避开甚至否定本身不善于的事物,大家都欢畅确定的东西;有些技术更强硬,可是只是根据特殊的客观条件和急需,假使您想做大,要么创设客观条件,要么把它构成要求……
事先有要调换的园友会用园子的短信息,好像个人资料里也不曾把邮箱展现出来。有趣味调换的就直接indreamluo@qq.com吧。
10.3. ps aux|grep redis
[test@test-168-251 ~]$ ps aux|grep redis test 3824 0.7 5.9 6742404 3885144 ? Ssl 2015 1639:13 /data/redis/bin/redis-server *:6379 [cluster] test 3831 0.5 3.9 6709636 2618536 ? Ssl 2015 1235:43 /data/redis/bin/redis-server *:6380 [cluster] |
终止redis实例,直接选取kill命令即可,如:kill 3831,重启和单机版相同,经过上述一文山会海操作后,重启会自动转换成cluster情势。。
11. redis cluster client
11.1. 指令行工具redis-cli
合法提供的指令行客户端工具,在单机版redis基础上指定参数“-c”即可。以下是在192.168.0.251上举行redis-cli的记录:
$ ./redis-cli -c -p 6379 127.0.0.1:6379> set foo bar -> Redirected to slot [12182] located at 192.168.0.253:6379 OK 192.168.0.253:6379> set hello world -> Redirected to slot [866] located at 192.168.0.251:6379 OK 192.168.0.251:6379> get foo -> Redirected to slot [12182] located at 192.168.0.253:6379 "bar" 192.168.0.253:6379> get hello -> Redirected to slot [866] located at 192.168.0.251:6379 "world"
查看集群中的节点: 192.168.0.251:6379> cluster nodes |
11.2. 从slaves读数据
暗许不大概从slaves读取数据,但建立连接后,执行五回命令READONLY ,即可从slaves读取数据。要是想再次恢复生机不可以从slaves读取数据,可以推行下命令READWRITE。
11.3. jedis(java cluster client)
官网:https://github.com/xetorthio/jedis
编程示例:
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"); |
11.4. r3c(C++ cluster client)
官网:https://github.com/eyjian/r3c
12. 激增节点
12.1. 添加一个新主(master)节点
先以单机版配置和起步好redis-server,然后执行命令:
./redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000 |
推行上边那条命令时,恐怕蒙受错误“[ERR] Sorry, can’t connect to node 127.0.0.1:7006”。引起该难题的由来只怕是因为ruby的版本过低(运行ruby -v可以查看ruby的本子),可以尝尝升级ruby再品尝,比如ruby 1.8.7版本就需求升级。对于Redis 3.0.5和Redis 3.2.0,使用Ruby 2.3.1操作正常。请留意升级到最新版本的ruby也大概遇到那一个指鹿为马。
另一个会挑起那些题材的来头是从Redis 3.2.0本子早先引入了“保养格局(protected mode),幸免redis-cli远程访问”,仅限redis-cli绑定到127.0.0.1才方可连接Redis server。
为了做到增进新主节点,可以暂时的倒闭爱惜情势,使用redis-cli,不指定-h参数(但足以指定-p参数,或许-h参数值为127.0.0.1)进入操作界面:CONFIG SET protected-mode no。
专注7006是新增的节点,而7000是已存在的节点(可为master或slave)。若是急需将7006改为某master的slave节点,执行命令:
cluster replicate 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e |
新加盟的master节点上并未其余数据(slots,运行redis命令cluster nodes可以观看那个场所)。当一个slave想成为master时,由于那些新的master节点不治本任何slots,它不参与选举。
可以行使工具redis-trib.rb的resharding天性为这么些新master节点分配slots,如:
redis-trib.rb reshard 127.0.0.1:7000,其中7000为集群中私下一个节点即可,redis-trib.rb将活动发现任何节点。
在reshard进程中,将会询问reshard多少slots:
How many slots do you want to move (from 1 to 16384)?,取值范围为1~16384,其中16384为redis cluster的装有的slots总数,比如想只移动100个,输入100即可。若是搬迁的slots数量多,应当设置redis-trib.rb的逾期参数–timeout值大一些。否则,迁移过程中易遇到超时错误“[ERR] Calling MIGRATE: IOERR error or timeout reading to target instance”,导致只已毕部分,只怕会造成数据丢失。
进而,会提示“What is the receiving node ID?”,输入新投入的master节点ID。进程中只要蒙受错误“Sorry, can’t connect to node 10.225.168.253:6380”,则或然须求暂时先关闭相应的爱慕格局。
借使在搬迁进程遇到上面那样的不当:
>>> Check for open slots… [WARNING] Node 192.168.0.3:6379 has slots in importing state (5461). [WARNING] Node 192.168.0.5:6380 has slots in migrating state (5461). [WARNING] The following slots are open: 5461 |
可以考虑采用命令“redis-trib.rb fix 192.168.0.3:6379”尝试修复。须要展示有节点处于migrating或importing状态,可以登录到相应的节点,使用命令“cluster setslot 5461 stable”修改,参数5461为题材显得的slot的ID。
12.2. 添加一个新从(slave)节点
./redis-trib.rb add-node –slave 127.0.0.1:7006 127.0.0.1:7000 |
小心这种措施,若是添加了七个slave节点,大概引致master的slaves不平均,比如有的有3个slave,其余只1个slave。可以在slave节点上实施redis命令“CLUSTER REPLICATE”举行调整,让它成为任何master的slave。“CLUSTER REPLICATE”带一个参数,即master ID,注意运用redis-cli -c登录到slave上实施。
地方方法没有点名7006的master,而是无度指定。下边方法可以显著指定为哪个master的slave:
./redis-trib.rb add-node –slave –master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7006 127.0.0.1:7000 |
13. 删减节点
从集群中删去一个节点:
./redis-trib del-node 127.0.0.1:7000 `<node-id>` |
先是个参数为集群中私下一个节点,第一个参数为必要删除节点的ID。
CLUSTER FORGET <node-id>
留神假如是删除一个master节点,则需求先将它管理的slots的迁走,然后才足以去除它。
14. 检讨节点状态
redis-trib.rb check 127.0.0.1:6380
如觉察如下那样的错误:
[WARNING] Node 192.168.0.11:6380 has slots in migrating state (5461).
[WARNING] The following slots are open: 5461
可以行使redis命令撤废slots迁移(5461为slot的ID):
cluster setslot 5461 stable
亟待留意,须登录到192.168.0.11:6380上执行redis的setslot子命令。
15. slots相关命令
CLUSTER ADDSLOTS slot1 [slot2] … [slotN] CLUSTER DELSLOTS slot1 [slot2] … [slotN] CLUSTER SETSLOT slot NODE node CLUSTER SETSLOT slot MIGRATING node CLUSTER SETSLOT slot IMPORTING node |
15.1. 迁移slosts
示范:将slot8从节点A迁移到节点B,有如下二种方法:
在节点B上执行:CLUSTER SETSLOT 8 IMPORTING A 或 在节点A上执行:CLUSTER SETSLOT 8 MIGRATING B |
15.2. redis-trib.rb rebalance
当有增减节点时,可以拔取命令:
redis-trib.rb rebalance 192.168.0.31:6379 –auto-weights
做一遍均衡,不难点可以只指定七个参数:“192.168.0.31:6379”为集群中已知的任何一个节点,参数“-auto-weights”表示自动权重。
16. 人造主备切换
在要求的slaves节点上执行命令:CLUSTER FAILOVER。
17. 翻看集群新闻
对应的redis命令为:cluster info,示例:
127.0.0.1:6381> cluster info cluster_state:ok 所有slots正常则显示为OK,否则为error cluster_slots_assigned:16384 多少slots被分配了,即多少被master管理了,16384为全部slots cluster_slots_ok:16384 有多少slots是正常的 cluster_slots_pfail:0 有多少slots可能处于异常状态,处于这个状态并不表示有问题,仍能继续提供服务 cluster_slots_fail:0 有多少slots处于异常状态,需要修复才能服务 cluster_known_nodes:10 集群中的节点数 cluster_size:3 集群中master个数 cluster_current_epoch:11 本地的当前时间变量,用于故障切换时生成独一无二的增量版本号 cluster_my_epoch:0 cluster_stats_messages_sent:4049 通过集群消息总线发送的消息总数 cluster_stats_messages_received:4051 通过过集通过群消息总线收到的消息总数 |
18. 难点排查
1) 假设最后一条日志为“16367:M 08 Jun 14:48:15.560 # Server started, Redis version 3.2.0”,节点状态一直终于fail状态,则只怕是aof文件损坏了,那时可以行使工具edis-check-aof –fix进行改动,如:
../../bin/redis-check-aof –fix appendonly-6380.aof
0x a1492b9b: Expected prefix ‘
AOF analyzed: size=2705928192, ok_up_to=2705927067, diff=1125
This will shrink the AOF from 2705928192 bytes, with 1125 bytes, to 2705927067 bytes
Continue? [y/N]: y