我在物理机上创建了5台虚拟机,搭建了一个ceph集群,结构如图:
具体的安装步骤参考文档:http://docs.ceph.org.cn/start/
http://www.centoscn.com/CentosServer/test/2015/0521/5489.html
一、磁盘读写性能
1. 单个osd磁盘写性能
[root@lrr-ceph1 osd]# echo 3 > /proc/sys/vm/drop_caches #清除缓存页,目录项和inodes
[root@lrr-ceph1 osd]# dd if=/dev/zero of=/var/lib/ceph/osd/lrr01 bs=1G count=1 oflag=direct #执行写命令
注:两个OSD同时写性能
[root@lrr-ceph1 osd]# for i in `mount | grep osd | awk '{print $3}'`; do (dd if=/dev/zero of=$i/lrr01 bs=1G count=1 oflag=direct $) ; done
2. 单个OSD同时读性能
[root@lrr-ceph1 osd]# dd if=/var/lib/ceph/osd/lrr01 of=/dev/null bs=2G count=1 iflag=direct
0+1 records in
0+1 records out
1073741824 bytes (1.1 GB) copied, 7.13509 s, 150 MB/s
注:两个OSD同时读性能
[root@lrr-ceph1 osd]# for i in `mount | grep osd | awk '{print $3}'`; do (dd if=$i/lrr01 of=/dev/null bs=1G count=1 iflag=direct &); done
二、CEPH 性能测试方法
ceph性能的测试包括:RADOS性能测试和RBD性能测试;
Rados性能测试工具:使用ceph自带的rados bench工具、使用rados losd-gen工具;
RBD性能测试工具:rbd bench-write进行块设备写性能测试、fio+rbd ioengine测试、fio +libaio测试。
1. Rados性能测试
1.1 使用ceph自带的rados bench工具进行测试
该工具的语法是:rados bench -p <pool_name> <seconds> <write|seq|rand> -b <block size> -t --no-cleanup
pool_name:测试所针对的存储池;
seconds:测试所持续的秒数;
<write|seq|rand>:操作模式,write:写,seq:顺序读;rand:随机读;
-b:block size,即块大小,默认为 4M;
-t:读/写并行数,默认为 16;
--no-cleanup 表示测试完成后不删除测试用数据。在做读测试之前,需要使用该参数来运行一遍写测试来产生测试数据,在全部测试结束后可以运行 rados -p <pool_name> cleanup 来清理所有测试数据。
i 写测试:
[root@lrr-ceph2 ~]# rados bench -p rbd 10 write --no-cleanup
Maintaining 16 concurrent writes of 4194304 bytes to objects of size 4194304 for up to 10 seconds or 0 objects
Object prefix: benchmark_data_lrr-ceph2_4445
sec Cur ops started finished avg MB/s cur MB/s last lat(s) avg lat(s)
0 0 0 0 0 0 - 0
1 16 16 0 0 0 - 0
2 16 16 0 0 0 - 0
。。。。
17 13 19 6 1.41038 0 - 10.7886
18 13 19 6 1.33207 0 - 10.7886
19 13 19 6 1.26201 0 - 10.7886
Total time run: 19.698032
Total writes made: 19
Write size: 4194304
Object size: 4194304
Bandwidth (MB/sec): 3.85825
Stddev Bandwidth: 0.551976
Max bandwidth (MB/sec): 1.71429
Min bandwidth (MB/sec): 0
Average IOPS: 0
Stddev IOPS: 0
Max IOPS: 0
Min IOPS: 0
Average Latency(s): 15.5797
Stddev Latency(s): 5.09105
Max latency(s): 19.6971
Min latency(s): 5.51094
ii 顺序读测试:
iii 随机读测试:
1.2 rados load-gen 工具
该工具的语法为:
# rados -p rbd load-gen
--num-objects 初始生成测试用的对象数,默认
--min-object-size 测试对象的最小大小,默认 1KB,单位byte
--max-object-size 测试对象的最大大小,默认 5GB,单位byte --min-op-len 压测IO的最小大小,默认 1KB,单位byte
--max-op-len 压测IO的最大大小,默认 2MB,单位byte
--max-ops 一次提交的最大IO数,相当于iodepth
--target-throughput 一次提交IO的历史累计吞吐量上限,默认 5MB/s,单位B/s
--max-backlog 一次提交IO的吞吐量上限,默认10MB/s,单位B/s
--read-percent 读写混合中读的比例,默认80,范围[, ] --run-length 运行的时间,默认60s,单位秒
在 ceph1上运行
rados -p pool100 load-gen --read-percent --min-object-size --max-object-size --max-ops --read-percent --min-op-len --max-op-len --target-throughput --max_backlog
的结果为:
WRITE : oid=obj-y0UPAZyRQNhnabq off= len=
op completed, throughput=16MB/sec
WRITE : oid=obj-nPcOZAc4ebBcnyN off= len=
op completed, throughput=20MB/sec
WRITE : oid=obj-sWGUAzzASPjCcwF off= len=
op completed, throughput=24MB/sec
WRITE : oid=obj-79r25fxxSMgVm11 off= len=
op completed, throughput=28MB/sec
该命令的含义是:在 1G 的对象上,以 iodepth = 1 顺序写入 block size 为 4M 的总量为 1G 的数据。其平均结果大概在 24MB/s,基本和 rados bench 的结果相当。
在 client 上,同样的配置,顺序写的BW大概在 20MB/s,顺序读的 BW 大概在 100 MB/s。
可见,与 rados bench 相比,rados load-gen 的特点是可以产生混合类型的测试负载,而 rados bench 只能产生一种类型的负载。但是 load-gen 只能输出吞吐量,只合适做类似于 4M 这样的大block size 数据测试,输出还不包括延迟。
2 rbd性能测试
2.1 使用rbd bench-write 进行块设备写性能测试
2.1.1 客户端准备
在执行如下命令来准备 Ceph 客户端:
root@client:/var# rbd create bd2 --size
root@client:/var# rbd info --image bd2
rbd image 'bd2':
size MB in objects
order ( kB objects)
block_name_prefix: rb.0.3841.74b0dc51
format:
root@client:/var# rbd map bd2
root@client:/var# rbd showmapped
id pool image snap device
pool1 bd1 - /dev/rbd1
rbd bd2 - /dev/rbd2
root@client:/var# mkfs.xfs /dev/rbd2
log stripe unit ( bytes) is too large (maximum is 256KiB)
log stripe unit adjusted to 32KiB
meta-data=/dev/rbd2 isize= agcount=, agsize= blks
= sectsz= attr=, projid32bit=
data = bsize= blocks=, imaxpct=
= sunit= swidth= blks
naming =version bsize= ascii-ci=
log =internal log bsize= blocks=, version=
= sectsz= sunit= blks, lazy-count=
realtime =none extsz= blocks=, rtextents=
root@client:/var# mkdir -p /mnt/ceph-bd2
root@client:/var# mount /dev/rbd2 /mnt/ceph-bd2/
root@client:/var# df -h /mnt/ceph-bd2/
Filesystem Size Used Avail Use% Mounted on
/dev/rbd2 1014M 33M 982M % /mnt/ceph-bd2
2.1.2 测试
rbd bench-write 的语法为:rbd bench-write <RBD image name>,可以带如下参数:
- --io-size:单位 byte,默认 4096 bytes = 4K
- --io-threads:线程数,默认 16
- --io-total:总写入字节,单位为字节,默认 1024M
- --io-pattern <seq|rand>:写模式,默认为 seq 即顺序写
分别在集群 OSD 节点上和客户端上做测试:
(1)在 OSD 节点上做测试
root@ceph1:~# rbd bench-write bd2 --io-total
bench-write io_size io_threads bytes pattern seq
SEC OPS OPS/SEC BYTES/SEC
273.19 2237969.65
286.84 2349818.65
...
288.00 2358395.28
288.29 2360852.64
elapsed: ops: ops/sec: 288.75 bytes/sec: 2363740.27
此时,块大小为 4k,IOPS 为 289,BW 为 2.36 MB/s (怎么 BW 是 block_size * IOPS 的两倍呢?)。
(2)在客户端上做测试
root@client:/home/s1# rbd bench-write pool.host/image.ph2 --io-total 1719973000 --io-size 4096000
bench-write io_size 4096000 io_threads 16 bytes 1719973000 pattern seq
SEC OPS OPS/SEC BYTES/SEC
1 5 3.41 27937685.86
2 19 9.04 68193147.96
3 28 8.34 62237889.75
5 36 6.29 46538807.31
...
39 232 5.86 40792216.64
40 235 5.85 40666942.19
elapsed: 41 ops: 253 ops/sec: 6.06 bytes/sec: 41238190.87
此时 block size 为 4M,IOPS 为 6, BW 为 41.24 MB/s。
root@client:/home/s1# rbd bench-write pool.host/image.ph2 --io-total 1719973000
bench-write io_size 4096 io_threads 16 bytes 1719973000 pattern seq
SEC OPS OPS/SEC BYTES/SEC
1 331 329.52 2585220.17
2 660 329.57 2521925.67
3 1004 333.17 2426190.82
4 1331 332.26 2392607.58
5 1646 328.68 2322829.13
6 1986 330.88 2316098.66
此时 block size 为 4K,IOPS 为 330 左右, BW 为 24 MB/s 左右。
备注:从 rbd bench-write vs dd performance confusion 中看起来,rados bench-write 似乎有bug。我所使用的Ceph 是0.80.11 版本,可能补丁还没有合进来。
2 使用fio+rbd ioengine
运行 apt-get install fio 来安装 fio 工具。创建 fio 配置文件:
root@client:/home/s1# cat write.fio
[write-4M]
description="write test with block size of 4M"
ioengine=rbd
clientname=admin
pool=rbd
rbdname=bd2
iodepth=32
runtime=120
rw=write #write 表示顺序写,randwrite 表示随机写,read 表示顺序读,randread 表示随机读
bs=4M
运行 fio 命令,但是出错:
root@client:/home/s1# fio write.fio
fio: engine rbd not loadable
fio: failed to load engine rbd
Bad option <clientname=admin>
Bad option <pool=rbd>
Bad option <rbdname=bd2>
fio: job write-4M dropped
fio: file:ioengines.c:99, func=dlopen, error=rbd: cannot open shared object file: No such file or directory
其原因是因为没有安装 fio librbd IO 引擎,因此当前 fio 无法支持 rbd ioengine:
root@client:/home/s1# fio --enghelp
Available IO engines:
cpuio
mmap
sync
psync
vsync
pvsync
null
net
netsplice
libaio
rdma
posixaio
falloc
e4defrag
splice
sg
binject
在运行 apt-get install librbd-dev 命令安装 librbd 后,fio 还是报同样的错误。参考网上资料,下载 fio 代码重新编译 fio:
$ git clone git://git.kernel.dk/fio.git
$ cd fio
$ ./configure
[...]
Rados Block Device engine yes
[...]
$ make
此时 fio 的 ioengine 列表中也有 rbd 了。fio 使用 rbd IO 引擎后,它会读取 ceph.conf 中的配置去连接 Ceph 集群。
下面是 fio 命令和结果:
root@client:/home/s1/fio# ./fio ../write.fio
write-4M: (g=): rw=write, bs=4M-4M/4M-4M/4M-4M, ioengine=rbd, iodepth=
fio-2.11--g82e6
Starting process
rbd engine: RBD version: 0.1.
Jobs: (f=): [W()] [100.0% done] [0KB/.0MB/0KB /s] [// iops] [eta 00m:00s]
write-4M: (groupid=, jobs=): err= : pid=: Sat Jun ::
Description : ["write test with block size of 4M"]
write: io=.0MB, bw=17397KB/s, iops=, runt= 60275msec
slat (usec): min=, max=, avg=1489.10, stdev=4907.83
clat (msec): min=, max=, avg=7399.86, stdev=1328.55
lat (msec): min=, max=, avg=7401.35, stdev=1328.67
clat percentiles (msec):
| .00th=[ ], .00th=[ ], .00th=[ ], .00th=[ ],
| .00th=[ ], .00th=[ ], .00th=[ ], .00th=[ ],
| .00th=[ ], .00th=[ ], .00th=[ ], .00th=[ ],
| .00th=[], .50th=[], .90th=[], .95th=[],
| .99th=[]
bw (KB /s): min=, max=, per=100.00%, avg=259334.50, stdev=6250.72
lat (msec) : =1.17%, >==98.83%
cpu : usr=0.24%, sys=0.03%, ctx=, majf=, minf=
IO depths : =2.3%, =5.5%, =12.5%, =25.0%, =50.4%, =4.3%, >==0.0%
submit : =0.0%, =100.0%, =0.0%, =0.0%, =0.0%, =0.0%, >==0.0%
complete : =0.0%, =97.0%, =0.0%, =0.0%, =3.0%, =0.0%, >==0.0%
issued : total=r=/w=/d=, short=r=/w=/d=, drop=r=/w=/d=
latency : target=, window=, percentile=100.00%, depth= Run status group (all jobs):
WRITE: io=.0MB, aggrb=17396KB/s, minb=17396KB/s, maxb=17396KB/s, mint=60275msec, maxt=60275msec Disk stats (read/write):
sda: ios=/, merge=/, ticks=/, in_queue=, util=6.18%
如果 iodepth = 1 的话,结果是:
root@client:/home/s1# fio/fio write.fio.dep1
write-4M: (g=): rw=write, bs=4M-4M/4M-4M/4M-4M, ioengine=rbd, iodepth=
fio-2.11--g82e6
Starting process
rbd engine: RBD version: 0.1.
Jobs: (f=): [W()] [100.0% done] [0KB/8192KB/0KB /s] [// iops] [eta 00m:00s]
write-4M: (groupid=, jobs=): err= : pid=: Sat Jun ::
Description : ["write test with block size of 4M"]
write: io=.0MB, bw=20640KB/s, iops=, runt= 50802msec
3 使用fio+libaio进行测试
libaio 是 Linux native asynchronous I/O。
几种测试模式:
随机写:
fio/fio -filename=/mnt/ceph-rbd2 -direct= -iodepth -thread -rw=randwrite -ioengine=libaio -bs=4M -size=1G -numjobs= -runtime= -group_reporting -name=read-libaio
这些参数的含义是:
filename:表示待测试的设备名称。
iodepth: libaio 会用这个 iodepth 值来调用 io_setup 准备个可以一次提交 iodepth 个 IO 的上下文,同时申请个io请求队列用于保持IO。
iodepth_batch:在压测进行的时候,系统会生成特定的IO请求,往io请求队列里面扔,当队列里面的IO个数达到 iodepth_batch 值的时候,
iodepth_batch_complete 和 iodepth_low: 调用 io_submit 批次提交请求,然后开始调用 io_getevents 开始收割已经完成的IO。 每次收割多少呢?由于收割的时候,超时时间设置为0,所以有多少已完成就算多少,最多可以收割 iodepth_batch_complete 值个。随着收割,IO队列里面的IO数就少了,那么需要补充新的IO。 什么时候补充呢?当IO数目降到 iodepth_low 值的时候,就重新填充,保证 OS 可以看到至少 iodepth_low 数目的io在电梯口排队着。
root@client:/home/s1# fio/fio -filename=/mnt/ceph-rbd2 -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=libaio -bs=4M -size=1G -numjobs=1 -runtime=120 -group_reporting -name=read-libaio read-libaio: (g=0): rw=randwrite, bs=4M-4M/4M-4M/4M-4M, ioengine=libaio, iodepth=1
fio-2.11-12-g82e6
Starting 1 thread
Jobs: 1 (f=1): [w(1)] [100.0% done] [0KB/94302KB/0KB /s] [0/23/0 iops] [eta 00m:00s]
read-libaio: (groupid=0, jobs=1): err= 0: pid=20256: Sun Jun 5 10:00:55 2016
write: io=1024.0MB, bw=102510KB/s, iops=25, runt= 10229msec
slat (usec): min=342, max=5202, avg=1768.90, stdev=1176.00
clat (usec): min=332, max=165391, avg=38165.11, stdev=27987.64
lat (msec): min=3, max=167, avg=39.94, stdev=28.00
clat percentiles (msec):
| 1.00th=[ 8], 5.00th=[ 18], 10.00th=[ 19], 20.00th=[ 20],
| 30.00th=[ 22], 40.00th=[ 25], 50.00th=[ 29], 60.00th=[ 31],
| 70.00th=[ 36], 80.00th=[ 47], 90.00th=[ 83], 95.00th=[ 105],
| 99.00th=[ 123], 99.50th=[ 131], 99.90th=[ 165], 99.95th=[ 165],
| 99.99th=[ 165]
bw (KB /s): min=32702, max=172032, per=97.55%, avg=99999.10, stdev=36075.23
lat (usec) : 500=0.39%
lat (msec) : 4=0.39%, 10=0.39%, 20=21.48%, 50=57.81%, 100=14.45%
lat (msec) : 250=5.08%
cpu : usr=0.62%, sys=3.65%, ctx=316, majf=0, minf=9
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued : total=r=0/w=256/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0
latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs):
WRITE: io=1024.0MB, aggrb=102510KB/s, minb=102510KB/s, maxb=102510KB/s, mint=10229msec, maxt=10229msec Disk stats (read/write):
sda: ios=0/1927, merge=0/1, ticks=0/30276, in_queue=30420, util=98.71%
随机读:fio/fio -filename=/mnt/ceph-rbd2 -direct= -iodepth -thread -rw=randread -ioengine=libaio -bs=4M -size=1G -numjobs= -runtime= - group_reporting -name=read-libaio 顺序写:fio/fio -filename=/mnt/ceph-rbd2 -direct= -iodepth -thread -rw=write -ioengine=libaio -bs=4M -size=1G -numjobs= -runtime= -group_reporting -name=read-libaio 随机写:fio/fio -filename=/mnt/ceph-rbd2 -direct= -iodepth -thread -rw=randwrite -ioengine=libaio -bs=4M -size=1G -numjobs= -runtime= -group_reporting -name=read-libaio
三、总结
1 测试工具小结
工具 | 用途 | 语法 | 说明 |
dd | 磁盘读写性能测试 | dd if=/dev/zero of=/root/testfile bs=1G count=1 oflag=direct/dsync/sync | https://www.thomas-krenn.com/en/wiki/Linux_I/O_Performance_Tests_using_dd |
iperf | 网络带宽性能测试 | https://iperf.fr/ | |
rados bench | RADOS 性能测试工具 | rados bench -p <pool_name> <seconds> <write|seq|rand> -b <block size> -t --no-cleanup |
|
rados load-gen | RADOS 性能测试工具 |
# rados -p rbd load-gen |
|
rbd bench-write | ceph 自带的 rbd 性能测试工具 |
rbd bench-write <RBD image name>
|
|
fio + rbd ioengine | fio 结合 rbd IO 引擎的性能测试工具 | 参考 fio --help |
|
fio + libaio | fio 结合 linux aio 的 rbd 性能测试 |
2 测试结果比较
所使用的命令:
- rbd bench-write pool.host/image.ph2 --io-total 1719973000 --io-size 4096000 --io-threads 1 --io-pattern rand/seq
- rados -p pool.host bench 20 write -t 1 --no-cleanup
- rados -p pool100 load-gen --read-percent 0 --min-object-size 1073741824 --max-object-size 1073741824 --max-ops 1 --read-percent 0/100 --min-op-len 4194304 --max-op-len 4194304 --target-throughput 1073741824 --max_backlog 1073741824
- ceph tell osd.0 bench
- fio/fio -filename=/dev/rbd4 -direct=1 -iodepth 1 -thread -rw=write/read/randwrite/randread -ioengine=libaio -bs=4M -size=1G -numjobs=1 -runtime=1800 -group_reporting -name=read-libaio
结果(仅在作者的测试环境的客户端节点上运行以上命令的输出):
操作 | dd 一个 OSD | dd 两个 OSD | rados load-gen | rados bench | rbd bench-write | ceph tell osd.0 bench | fio + rbd | fio + libaio |
顺序写 | 165 | 18 | 18 | 18 | 74 MB/s (IOPS 9) |
40 MB/s |
21 (iops 5) | 18(iops 4) |
随机写 | 67.8 MB/s (IOPS 8) | 19 (iops 4) | 16(iops 4) | |||||
顺序读 | 460 | 130 | 100 | 109 | N/A | 111(iops 27) | 111(iops 27) | |
随机读 | 112 | N/A | 115(iops 28) | 128(iops 31) |
简单结论(由于环境、测试方法和数据有限,这些结论不一定正确,有些只是猜测,需要进一步研究,仅供参考):
- rados bench 和在两个 OSD 上同时做 dd 的性能差不多。
- fio + rbd 和 fio + libaio 的结果差不多,相比之下 fio + rbd 还要好一点点。
- fio 顺序写和读的 BW 和两个 OSD 同时写和读的 BW 差不多。
- fio 顺序写的 BW 差不多是 单个 OSD 的 bench 的一半 (因为我的 pool 的 size 为 2)。
- rados load-gen,rodos bench 和 fio rbd/libaio 的结果都差不多,可见都可以信任,只是每一种都有其特长,选择合适你的测试应用场景的某个即可。
- rdb bench-write 的值明显偏高,原因未知,也许存在 bug,详情可参考 rbd bench-write vs dd performance confusion,选择时需慎重。
参考链接:
http://tracker.ceph.com/projects/ceph/wiki/Benchmark_Ceph_Cluster_Performance
Ceph Performance Analysis: fio and RBD
http://www.quts.me/page2/
http://events.linuxfoundation.org/sites/events/files/slides/Vault-2015.pdf
http://www.cnblogs.com/sammyliu/p/5557666.html
ceph--磁盘和rbd、rados性能测试工具和方法的更多相关文章
-
Ceph性能测试工具和方法。
0. 测试环境 同 Ceph 的基本操作和常见故障排除方法 一文中的测试环境. 1. 测试准备 1.1 磁盘读写性能 1.1.1 单个 OSD 磁盘写性能,大概 165MB/s. root@ceph1 ...
-
理解 OpenStack + Ceph (8): 基本的 Ceph 性能测试工具和方法
本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...
-
基本的Ceph性能测试工具和方法
测试环境 1. 测试准备 1.1 磁盘读写性能 1.1.1 单个 OSD 磁盘写性能,大概 165MB/s. root@ceph1:~# echo 3 > /proc/sys/vm/drop_c ...
-
理解 OpenStack + Ceph (3):Ceph RBD 接口和工具 [Ceph RBD API and Tools]
本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...
-
6款实用的硬盘、SSD固态硬盘、U盘、储存卡磁盘性能测试工具
一.检测工具名称汇总 HDTune ATTO Disk Benchmark CrystalDiskMark AS SSD Benchmark Parkdale CrystalDiskInfo 二.各项 ...
-
Linux系统性能测试工具(六)——磁盘io性能工具之dd
本文介绍关于Linux系统(适用于centos/ubuntu等)的磁盘io性能测试工具-dd.磁盘io性能测试工具包括: fio: dd
-
Linux系统性能测试工具(五)——磁盘io性能工具之fio
本文介绍关于Linux系统(适用于centos/ubuntu等)的磁盘io性能测试工具-fio.磁盘io性能测试工具包括: fio: dd
-
磁盘性能测试工具之fio
fio是测试磁盘性能的一个非常好的工具,用来对硬件进行压力测试和验证. 注意事项 CentOS 6.5等较老版本的操作系统用fdisk创建分区时,默认为非4KB对齐选择初始磁柱编号,对性能有较大的影响 ...
-
开源多线程性能测试工具-sysbench
导读 sysbench是一款开源的多线程性能测试工具,可以执行CPU/内存/线程/IO/数据库等方面的性能测试.数据库目前支持MySQL/Oracle/PostgreSQL.本文主要演示Mysql测试 ...
随机推荐
-
C#夯实基础之接口(《CLR via C#》读书笔记)
一. 接口的类型 接口是引用类型.因此从值类型赋值给接口是需要装箱的.如下所示: class Program { static void Main(string[] args) { ISay catS ...
-
shell常用命令之curl: -w,–write-out参数详解
顾名思义,write-out的作用就是输出点什么.curl的-w参数用于在一次完整且成功的操作后输出指定格式的内容到标准输出. 输出格式由普通字符串和任意数量的变量组成,输出变量需要按照%{varia ...
-
网站地图sitemap.xml的格式
URL列表—XML格式及规范说明: 标签名称 属性 标签说明 标签类型 标签限制 可选/必选 urlset / urlset用来标记整个文档的开头 / / 必选 url / u ...
-
Singlton设计模式
单例定义: 确保一个类只有一个实例,并提供全局访问点. 适用场景: 1.) 当系统中某个类必须仅有一个实例对象,同时访问该系统的所有访问者必须访问同一个实例对象时,且该对象实例自身占用资源又不大时. ...
-
使用IDEA自带maven建java项目时报错。
今天用IDEA建立maven项目时报错: [INFO] Scanning for projects... [INFO] Searching repository for plugin with pre ...
-
C# 泛型 Func<;object, string, bool>; filter
Func<object, string, bool>是泛型,你可以先把他看成一个普通类型,比如stringpublic class Func{ } // 自定义个普通类. Func fil ...
-
bootstarp模板02
HTML代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="ut ...
-
AS中jar包和aar包区别及导入导出
发布时间:2018-01-18 来源:网络 上传者:用户 关键字: 导出 导入 区别 包和 aar jar 发表文章 摘要:jar包和aar包区别*.jar:只包含class文件与清单文件,不包含资源 ...
-
axios POST提交数据的三种请求方式写法
1.Content-Type: application/json import axios from 'axios' let data = {"code":"1234&q ...
-
洛谷 P4427 求和
传送门啦 思路: 开始不肿么容易想到用倍增,但是想到需要求 $ Lca $ ,倍增这种常数小而且快的方法就很方便了.求 $ Lca $ 就是一个最普通的板子.那现在考虑怎么求题目中的结果. 树上差分可 ...