第二章主要讲了三个问题
- 40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数
- 将一个n元一维向量向左旋转i个位置
- 给定一个英文字典,找出其中的所有的变位词集合。例如”pots”, “stop”, “tops”。
前游戏热爱者
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
1 | $ hexo new "My New Post" |
More info: Writing
1 | $ hexo server |
More info: Server
1 | $ hexo generate |
More info: Generating
1 | $ hexo deploy |
More info: Deployment
Sentinel是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器以及这些主服务器属下的所有从服务器,并在被监视的主服务器进去下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
今天讲一下多机数据库的实现。
假设现在有两个Redis服务器,地址分别为127.0.0.1:6379和127.0.0.1:12345,如果我们向服务器127.0.0.1:12345发送以下命令127.0.0.1:12345: SLAVEOF 127.0.0.1 6379
,那么12345将成为6379的从服务器。
Redis的复制功能分为同步sync和命令传播command propagate两个操作:
从服务器对主服务器的同步操作需要通过向主服务器发送SYNC命令来完成,以下是SYNC命令的执行步骤:
主服务器会将自己执行的写命令发送给从服务器执行,当从服务器执行了相同的写命令之后,主从服务器将再次回到一致状态。
旧版复制功能对于断线后重复制,采用的是跟初次复制一样的策略,导致断线重复制成本非常高。
Redis从2.8版本开始,使用PSYNC命令代替SYNC命令来执行复制时的同步操作。
PSYNC命令具有完整重同步和部分重同步两种模式:
部分重同步功能由以下三个部分构成
执行复制的双方-主服务器和从服务器会分别维护一个复制偏移量
复制积压缓冲区是由主服务器维护的一个固定长度先进先出队列,默认大小为1MB。
当从服务器重新连上主服务器时,从服务器会通过PSYNC命令将自己的复制偏移量offset发送给主服务器,主服务器会根据这个复制偏移量来决定对从服务器执行何种同步操作。要么是完全重同步,要么是部分重同步
当从服务器对主服务器进行初次复制时,主服务器会将自己的运行ID传送给从服务器,而从服务器则会将这个运行ID保存起来。
在命令传播节点,从误区默认会以每秒一次的频率才,向主服务器发送命令:REPLCONF ACK <replication_offset>
,其中replication_offset是从服务器当前的复制偏移量,主要有三个作用:
Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结构的db数组中,db数组的每个项都是一个redis.h/redisDb结构,每个redisDb结构代表一个数据库。1
2
3
4
5
6
7struct redisServer {
// 一个数组,保存着服务器中的所有数据库
redisDb *db;
// 服务器的数据库数量,默认为16
int dbNum;
}
Redis是一个键值对数据库服务器买服务器中的每个数据库都由一个redis.h/redisDb结构表示,其中,redisDb结构的dict字典保存了数据库中的所有键值对,我们将这个字典称为键空间。1
2
3
4
5
6
7struct redisDb {
// 数据库键空间,保存着数据库中的所有键值对
dict *dict;
// 过期字典,保存着键的过期时间
dict *expires;
}
通过EXPIRE命令或者PEXPIRE命令,客户端可以以秒或者毫秒精度为数据库中的某个键设置生存时间,在经过指定的秒数或毫秒数之后,服务器就会自动删除生存时间为0的键。
EXPIREAT或PEXPIREAT,以秒或者毫秒精度给数据库中的某个键设置过期时间。
TTL 查看过期时间,time to live
Redis服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,服务器可以很好地在合理使用CPU时间和避免浪费内存空间之间取得平衡。
过期键不会被保存到RDB文件中
过期键不会被保存到AOF文件中
网上搜一下idea+spring关键字出来的都是Spring MVC项目,我只是想学习Spring,根本不需要什么web项目啊。
废话不多说,直接上流程
1 | <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> |
这是spring的两个核心依赖,稍等一段时间idea会auto import所有的依赖。
1 | package com.stefler; |
在applicationContext.xml中添加bean配置
1 | <?xml version="1.0" encoding="UTF-8"?> |
直接运行刚刚InfoCollect中的main函数即可。
自从转了Java开发之后,就一直会面对各种XML和JSON,XML多了之后看起来就特别难看,每次都需要去一个网站的在线XML格式化工具,反正很麻烦就是了。
然后在chrome的插件里也没有找到好用的,今天终于找到一个好用的插件了,sublime text中安装一个插件indent XML,安装好之后,点击菜单栏中的selection->format->选择indent或者auto indent都行,或者快捷键CTRL + F。
nice job~
ZooKeeper是一个开放源代码的分布式协调服务,由雅虎创建,是Google Chubby的开源实现。ZooKeeper的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。
ZooKeeper可以保证如下分布式一致性特性:
ZooKeeper致力于提供一个高性能、高可用,且具有严格的顺序访问控制能力的分布式协调服务。
ZooKeeper没有沿用船用的slave/master概念,而是引入了Leader、Follower和Observer三种角色。ZooKeeper集群中的所有机器通过一个Leader选举过程来选定一台被称为“Leader”的机器,Leader服务器为客户端提供读和写服务。Follower和Observer都能提供读服务,唯一的区别在于Observer机器不参与Leader选举过程,也不参与写操作的“过半写成功”策略。
客户端和服务器之间建立一个TCP长连接,通过心跳检测与服务器保持有效的会话,也能够向ZooKeeper服务器发生请求并接受响应,通过来能够通过该连接接收来自服务器的Watch时间通知。
指数据模型中的数据单元。ZooKeeper将所有数据村粗在内存中,数据模型是一棵树,由斜杠进行分隔的路径就是一个Znode,例如/foo/path1.每个Znode上都会保存自己的数据内容,同事还会保存一系列属性信息。
每个Znode都会维护一个叫做Stat的数据结构,Stat中记录了这个Znode的三个数据版本,分别是version-当前Znode的版本,cversion-当前Znode子节点的版本,aversion-当前Znode的acl版本。
事件监听器。ZooKeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,ZooKeeper服务端会将时间通知到感兴趣的客户端上去,该机制是ZooKeeper实现分布式协调服务的重要特性。
access control lists来进行权限控制。ZooKeeper定义了如下5种权限:
ZooKeeper Atomic Broadcast, ZooKeeper原子消息广播协议。ZooKeeper使用一个单一的主进程来接收并处理客户端的所有事务请求,并采用ZAB的原子广播协议,将服务器数据的状态变更以书屋Proposal的形式广播到所有的副本进程上去。
ZAB协议的核心是定义了对于那些会改变ZooKeeper服务器数据状态的事务请求的处理方式,即:
所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为Leader服务器,而余下的其他服务器则称为Follower服务器。Leader服务器负责将一个客户端事务请求转换成一个事务Proposal(提议),并将该Proposal分发给集群中所有的Follower服务器。之后Leader服务器需要等待所有Follower服务器的反馈,一旦超过半数的Follower服务器进行了正确的反馈后,那么Leader就会再次向所有的Follower服务器分发Commit消息,要求其将前一个Proposal进行提交。
针对客户端的事务请求,Leader服务器会为其生成对应的事务Proposal,并将其发送给集群中其余所有的机器,然后再分别收集各自的选票,最后进行事务提交。
核心:能够确保提交已经被Leader提交的事务Proposal,同时丢弃已经被跳过的事务Proposal。
在windows上部署伪集群模式的链接,注意需要给每个机器的data目录下添加一个myid文件。
http://blog.csdn.net/morning99/article/details/40426133
启动zkCli.cmd -server ip:host
Zookeeper zk = new Zookeeper();
节点类型共有四种
zkClient.create()
Zookeeper不支持递归创建,即无法在父节点不存在的情况下创建一个子节点。
zkClient.delete()
在Zookeeper中,只允许删除叶子节点。也就是说如果一个节点存在至少一个子节点的话,那么该节点将无法被直接删除,必须先删除掉其所有子节点。
zkClient.getChildren()
调用getChildren()获取到的节点列表,都是数据节点的相对节点路径。
Zookeeper服务端在向客户端发送Watcher”NodeChildrenChanged”事件通知的时候,仅仅只会发出一个通知,而不会把节点的变化情况发送给客户端,需要客户端自己重新获取。另外,由于Watcher通知是一次性的,即一旦触发一次通知后,该Watcher就失效了,因此客户端需要反复注册Watcher。
zkClient.getData()
节点的数据内容或是节点的数据版本编号,都被看作是Zookeeper节点的编号。
setData(final String path, byte date[], int version)
CAS理论,对于值V,每次更新前都会比对其值是否是预期值A,只有符合预期,才会将V原子化地更新到新值B。
如果传入的version为-1,就是告诉Zookeeper服务器,客户端需要基于数据的最新版本进行更新操作,没有原子性要求。
zkClient.exists()
当客户端对一个数据节点添加了权限信息后,对于删除操作而言,其作用范围是其子节点。也就是说,当我们对一个数据节点添加权限信息后,依然可以自由地删除这个节点,但是对于这个节点的子节点,就必须使用相应的权限信息才能够删除掉它。