0%

最近需要对文件做一些处理,之前接触得比较多的还是基于流的IO,但现在用得比较多的还是NIO(New IO),可以理解为Non-blocking IO。

缓冲区(Buffer)

缓冲区主要是负责数据的存取的。

除了boolean这个基础类型外,其他数据类型都对应一个缓冲Buffer。

1
2
3
4
5
6
7
ByteBuffer
CharBuffer
ShortBuffer
IntBuffer
LongBuffer
FloatBuffer
DoubleBuffer

两个核心方法

1
2
put() 存入数据到缓冲区
get() 从缓冲区获取数据

四个核心属性

  • capacity

容量,一旦声明,不可改变

  • limit

界限,表示缓冲区可以操作数据的大小。limit后数据不能进行读写操作

  • position

位置,表示缓冲区正在操作数据的位置

  • mark

标记,记录当前position的位置,后续操作之后,可以通过reset()恢复到mark的位置。

实例

1. 分配一个指定大小的缓冲区

1
2
3
4
5
6
7
8
9
10
11
12
13
String str = "abcde";

ByteBuffer buffer = ByteBuffer.allocate(1024);

System.out.println("--- allocate() ---");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity());
/**
* 0
* 1024
* 1024
*/

2. 执行put()把数据存入缓冲区

1
2
3
4
5
6
7
8
9
10
11
buffer.put(str.getBytes());

System.out.println("--- put() ---");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity());
/**
* 5
* 1024
* 1024
*/

3. 切换到读取数据模式

1
2
3
4
5
6
7
8
9
10
11
buffer.flip();

System.out.println("--- flip() ---");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity());
/**
* 0
* 5
* 1024
*/

4. 执行get()读取缓冲区数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
byte[] bytes = new byte[buffer.limit()];
buffer.get(bytes);

System.out.println("--- get() ---");
System.out.println(new String(bytes));

System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity());
/**
* abcde
* 5
* 5
* 1024
*/

5. 重新读取缓冲区

1
2
3
4
5
6
7
8
9
10
11
buffer.rewind();

System.out.println("--- rewind() ---");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity());
/**
* 0
* 5
* 1024
*/

6. mark/reset

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
buffer.get(bytes, 0, 2);
System.out.println(new String(bytes, 0, 2));
buffer.mark();
buffer.get(bytes, 2, 2);

buffer.reset();

System.out.println("--- reset() ---");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity());
/**
* 2
* 5
* 1024
*/

if (buffer.hasRemaining()) {
System.out.println(buffer.remaining());
/**
* 3
*/
}

7. 清空缓冲区

1
2
3
4
5
6
7
8
9
10
11
buffer.clear();

System.out.println("--- clear() ---");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity());
/**
* 0
* 1024
* 1024
*/

拉取CentOS镜像

1
docker pull centos

然后启动容器并进入容器。

安装GlusterFS软件

安装GlusterFS的源

1
yum install centos-release-gluster

安装这个的目的是接下来在安装glusterfs-server等包时,能找到源。

安装GlusterFS相关软件

1
yum install -y glusterfs glusterfs-server glusterfs-fuse glusterfs-rdma

创建文件夹

1
mkdir -p /gluster/data/

可以把iproute等基本工具安装上。

1
yum install -y iproute

生成一个新的镜像,gluster-centos

运行gluster-centos镜像实例

测试最基础的glusterFS功能,启动两个容器就可以。

1
docker run -dit --privileged simon/gluster-centos bash

这里需要注意的是需要使用--privileged这个参数,不然在创建volume时会有Setting extended attributes failed, reason: Operation not permitted.错误。

node hostname ip
node1 172.17.0.2 172.17.0.2
node2 172.17.0.3 172.17.0.3

创建GlusterFS卷

进入node1节点

进入node1, 172.17.0.2节点,peer probe另一个节点,执行命令

1
2
gluster peer probe 172.17.0.3
peer probe: success.

查看状态

1
2
3
4
5
6
gluster peer status
Number of Peers: 1

Hostname: 172.17.0.3
Uuid: 6b04331d-6fe9-4d78-937e-b10c69f476fa
State: Peer in Cluster (Connected)

创建复本卷

1
2
3
4
5
gluster volume create gv0 replica 2 172.17.0.2:/gluster/data 172.17.0.3:/gluster/data
Replica 2 volumes are prone to split-brain. Use Arbiter or Replica 3 to avoid this. See: http://docs.gluster.org/en/latest/Administrator%20Guide/Split%20brain%20and%20ways%20to%20deal%20with%20it/.
Do you still want to continue?
(y/n) y
volume create: gv0: failed: The brick 172.17.0.3:/gluster/data is being created in the root partition. It is recommended that you don't use the system's root partition for storage backend. Or use 'force' at the end of the command if you want to override this behavior.

按提示,增加force参数

如果在启动容器时,没有设置--privileged参数,则会报如下错误。

1
2
3
gluster volume create gv0 replica 2 172.17.0.2:/gluster/data 172.17.0.3:/gluster/data force
volume create: gv0: failed: Glusterfs is not supported on brick: 172.17.0.2:/gluster/data.
Setting extended attributes failed, reason: Operation not permitted.

所以只能删除容器,再次启动,并加入--privileged参数。

再次执行gluster volume create命令,执行成功。

1
2
gluster volume create gv0 replica 2 172.17.0.2:/gluster/data 172.17.0.3:/gluster/data force
volume create: gv0: success: please start the volume to access data

启动卷

1
2
gluster volume start gv0
volume start: gv0: success

查看卷信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
gluster volume info

Volume Name: gv0
Type: Replicate
Volume ID: 065914c6-38b0-4ef6-ad76-c190ea0cfb0c
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: 172.17.0.2:/gluster/data
Brick2: 172.17.0.3:/gluster/data
Options Reconfigured:
performance.client-io-threads: off
nfs.disable: on
transport.address-family: inet

创建GlusterFS客户端

安装GlusterFS客户端软件

主要就是安装glusterfs-fuse

1
yum install -y glusterfs glusterfs-fuse

启动一个gluster-centos容器也可以的。挂载点/gluster/data已经创建好了的。

以glusterfs方式挂载

1
mount -t glusterfs 172.17.0.2:gv0 /gluster/data

此时,在客户端/gluster/data看到的文件,就是分布式系统的文件了。可以像操作本地文件一样操作文件了。

CentOS 7环境修改主机名

修改主机名

1
hostnamectl set-hostname node1

立即生效,重启以后也不会失效。

查看主机名

1
2
hostname
node1

设置hosts

设置hostname对应的ip,主要是在其他节点上面设置node1节点的IP

1
vi /etc/hosts

CentOS 6环境修改主机名

在文件/etc/sysconfig/network里面添加

1
HOSTNAME=node2

重启生效。