IBM 的 POWER 处理器比较 X86 处理器

硬件体系

从处理能力来说,单Hz的处理能力x86已经超过了Power系列,这是毋庸置疑的。但是Power有其明显的优点。它采用了标准的SMP结构,也就是说对于内存来说所有CPU访问的速度都是一致的,而x86采用了NUMA结构,这就是说CPU和内存是分区的,每个CPU访问自己的这部分内存特别快,但是如果需要访问其它部分那就要走QPI总线(现在已经在不断改进了),这也客观上造成了随着CPU数量的增多,处理能力的增长Power系列的线性程度远好于x86(这也是为什么很少会用4路以上的x86服务器)。而且作为小型机,封闭系统,其设计更加完整紧凑,综合起来性能强于x86

软件体系

硬件体系是自己的,操作系统也是自己的(AIX等),所以整合起来Power系列的整体稳定性要强于x86服务器,而且运维也方便(特别是对于一些外围硬件,如果使用IBM更加容易用),抗压能力也强(小型机90%的CPU占用率,运行几个星期可能都OK,x86几天就估计出问题了)
但是Power系列的小型机的价格太高了,而且已经赶不上技术的变化了,由于Google的崛起,云计算的兴盛,现在的分布式系统的成熟度越来越高,系统已经越来越不依赖几台小型机来提供稳定可靠性,而是通过集群来提供,性能也能够通过分布式的处理来解决。所以x86的使用越来越广泛,而最新的一些低成本但是能够带来高效能的新技术都在x86体系下得到应用(x86市场占有率高,也开放),而Power系列由于其封闭的特性,反而难以得到应用,所以Power系列的小型机优势越来越不明显,已经在逐渐退出历史舞台了。

后记

AIX is an open operating system from IBM that is based on a version of UNIX.
ibm小型机的系统是AIX, 所以相关的软件也要on aix, 比如oracle on aix,
不过ibm小型机也可以安装linux,因为linux也可以运行在power处理器, Power ISA指令集

git 分支介绍

local branch

You can view a list of all the local branches on your machine by running git branch:

1
2
3
$ git branch
master
new-feature

Each local branch has a file under .git/refs/heads/:

1
2
$ ls -F .git/refs/heads/
master new-feature

There are two types of local branches on your machine: non-tracking local branches, and tracking local branches.

Non-tracking local branches

Non-tracking local branches are not associated with any other branch. You create one by running git branch <branchname>.

Tracking local branches

Tracking local branches are associated with another branch, usually a remote-tracking branch. You create one by running git branch - track <branchname> [<start-point>].
You can view which one of your local branches are tracking branches using git branch -vv:

1
2
3
$ git branch -vv
master b31f87c85 [origin/master] Example commit message
new-feature b760e04ed Another example commit message

From this command’s output, you can see that the local branch master is tracking the remote-tracking branch origin/master, and the local branch new-feature is not tracking anything.
Another way to see which branches are tracking branches is by having a look at .git/config.
Tracking local branches are useful. They allow you to run git pull and git push, without specifying which upstream branch to use. If the branch is not set up to track another branch, you’ll get an error like this one:

1
2
3
4
5
6
7
8
$ git checkout new-feature
$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details
git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:
git branch - set-upstream new-feature <remote>/<branch>

Remote-tracking branches (still on your machine)

You can view a list of all the remote-tracking branches on your machine by running git branch -r:

1
2
3
4
$ git branch -r
bitbucket/master
origin/master
origin/new-branch

Each remote-tracking branch has a file under .git/refs/<remote>/:

1
2
3
4
5
6
7
$ tree -F .git/refs/remotes/
.git/refs/remotes/
├── bitbucket/
│ └── master
└── origin/
├── master
└── new-branch

Think of your remote-tracking branches as your local cache for what the remote machines contain. You can update your remote-tracking branches using git fetch, which git pull uses behind the scenes.
Even though all the data for a remote-tracking branch is stored locally on your machine (like a cache), it’s still never called a local branch. (At least, I wouldn’t call it that!) It’s just called a remote-tracking branch.

Branches on a remote machine:

You can view all the remote branches (that is, the branches on the remote machine), by running git remote show <remote>:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git remote show origin
* remote origin
Fetch URL: git@github.com:Flimm/example.git
Push URL: git@github.com:Flimm/example.git
HEAD branch: master
Remote branches:
io-socket-ip new (next fetch will store in remotes/origin)
master tracked
new-branch tracked
Local ref configured for 'git pull':
master merges with remote master
new-branch merges with remote new-branch
Local ref configured for 'git push':
master pushes to master (up to date)
new-branch pushes to new-branch (fast-forwardable)

This git remote command queries the remote machine over the network about its branches. It does not update the remote-tracking branches on your local machine, use git fetch or git pull for that.

example

git pull [] [ […​]]

git merge [-n] [ - stat] [ - no-commit] [ - squash] [ - [no-]edit]
[-s ] [-X ] [-S[]]
[ - [no-]allow-unrelated-histories]
[ - [no-]rerere-autoupdate] [-m ] [-F ] […​]
从官方的文档来看,git merge是没有repository参数的

1
$ git pull origin next

这个pull的直接就是远程的分支, 他是下面两个命令的结合体

1
2
$ git fetch origin
$ git merge origin/next

这个先把远程的所有分支fetch过来,然后把远程跟踪分支merge到当前分支,origin/next这种分支是存在本地的,虽然叫远程跟踪分支
把远程的分支fetch过来可以看到如下, fetch就是把远程的东西拿到本地的仓库,也就是origin/develop

1
2
3
4
5
6
7
8
C:\git\testgit>git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://gitprod.statestr.com/e587214/testgit
8ce7bef..0605953 develop -> origin/develop

ref

https://stackoverflow.com/questions/16408300/what-are-the-differences-between-local-branch-local-tracking-branch-remote-bra/24785777

hive vs hbase

  1. Hive中的表是纯逻辑表,就只是表的定义等,即表的元数据。Hive本身不存储数据,它完全依赖HDFS和MapReduce。这样就可以将结构化的数据文件映射为为一张数据库表,并提供完整的SQL查询功能,并将SQL语句最终转换为MapReduce任务进行运行。 而HBase表是物理表,适合存放非结构化的数据。
  2. Hive是基于MapReduce来处理数据,而MapReduce处理数据是基于行的模式;HBase处理数据是基于列的而不是基于行的模式,适合海量数据的随机访问。
  3. HBase的表是疏松的存储的,因此用户可以给行定义各种不同的列;而Hive表是稠密型,即定义多少列,每一行有存储固定列数的数据。
  4. Hive使用Hadoop来分析处理数据,而Hadoop系统是批处理系统,因此不能保证处理的低迟延问题;而HBase是近实时系统,支持实时查询。
  5. Hive不提供row-level的更新,它适用于大量append-only数据集(如日志)的批任务处理。而基于HBase的查询,支持和row-level的更新。
  6. Hive提供完整的SQL实现,通常被用来做一些基于历史数据的挖掘、分析。而HBase不适用与有join,多级索引,表关系复杂的应用场景。

win10 disable auto-update

被windows 10 自动更新折磨了很久,今天终于找到了办法
运行regedit打开注册表,找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services下面的wuauserv服务,然后把右边的ImagePath改成一个错误的,然后update就彻底歇菜了

spark 闭包

什么叫闭包: 跨作用域访问函数变量。又指的一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

Spark闭包的问题引出:
在spark中实现统计List(1,2,3)的和。如果使用下面的代码,程序打印的结果不是6,而是0。这个和我们编写单机程序的认识有很大不同。为什么呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
object Test {
def main(args:Array[String]):Unit = {
val conf = new SparkConf().setAppName("test");
val sc = new SparkContext(conf)

val rdd = sc.parallelize(List(1,2,3))
var counter = 0
//warn: don't do this
rdd.foreach(x => counter += x)
println("Counter value: "+counter)

sc.stop()
}
}

问题分析:
counter是在foreach函数外部定义的,也就是在driver程序中定义,而foreach函数是属于rdd对象的,rdd函数的执行位置是各个worker节点(或者说worker进程),main函数是在driver节点上(或者说driver进程上)执行的,所以当counter变量在driver中定义,被在rdd中使用的时候,出现了变量的“跨域”问题,也就是闭包问题。

问题解释:
对于上面程序中的counter变量,由于在main函数和在rdd对象的foreach函数是属于不同“闭包”的,所以,传进foreach中的counter是一个副本,初始值都为0。foreach中叠加的是counter的副本,不管副本如何变化,都不会影响到main函数中的counter,所以最终打印出来的counter为0.

当用户提交了一个用scala语言写的Spark程序,Spark框架会调用哪些组件呢?首先,这个Spark程序就是一个“Application”,程序里面的mian函数就是“Driver Program”, 前面已经讲到它的作用,只是,dirver程序的可能运行在客户端,也有可有可能运行在spark集群中,这取决于spark作业提交时参数的选定,比如,yarn-client和yarn-cluster就是分别运行在客户端和spark集群中。在driver程序中会有RDD对象的相关代码操作,比如下面代码的newRDD.map()

1
2
3
4
5
6
7
8
9
10
11
class Test{
def main(args: Array[String]) {
val sc = new SparkContext(new SparkConf())
val newRDD = sc.textFile("")

newRDD.map(data => {
//do something
println(data.toString)
})
}
}

涉及到RDD的代码,比如上面RDD的map操作,它们是在Worker节点上面运行的,所以spark会透明地帮用户把这些涉及到RDD操作的代码传给相应的worker节点。如果在RDD map函数中调用了在函数外部定义的对象,因为这些对象需要通过网络从driver所在节点传给其他的worker节点,所以要求这些类是可序列化的,比如在Java或者scala中实现Serializable类,除了java这种序列化机制,还可以选择其他方式,使得序列化工作更加高效。worker节点接收到程序之后,在spark资源管理器的指挥下运行RDD程序。不同worker节点之间的运行操作是并行的。

​在worker节点上所运行的RDD中代码的变量是保存在worker节点上面的,在spark编程中,很多时候用户需要在driver程序中进行相关数据操作之后把该数据传给RDD对象的方法以做进一步处理,这时候,spark框架会自动帮用户把这些数据通过网络传给相应的worker节点。除了这种以变量的形式定义传输数据到worker节点之外,spark还另外提供了两种机制,分别是broadcast和accumulator。相比于变量的方式,在一定场景下使用broadcast比较有优势,因为所广播的数据在每一个worker节点上面只存一个副本,而在spark算子中使用到的外部变量会在每一个用到它的task中保存一个副本,即使这些task在同一个节点上面。所以当数据量比较大的时候,建议使用广播而不是外部变量。

随机生成大文件

code

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
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Random;

public class Test {
public static void main(String[] args) throws IOException {
byte[] buffer = "Help I am trapped in a fortune cookie factory\n".getBytes();
byte[] buffer2 = "good morning boy".getBytes();
int number_of_lines = 400000*20;

Random rand = new Random();


FileChannel rwChannel = new RandomAccessFile("mylarge.txt", "rw").getChannel();
ByteBuffer wrBuf = rwChannel.map(FileChannel.MapMode.READ_WRITE, 0, buffer.length * number_of_lines);
for (int i = 1; i < number_of_lines; i++)
{
int n = rand.nextInt(50) + 1;
if (n % i == 0) {
wrBuf.put(buffer);
} else {
wrBuf.put(buffer2);
}

}
rwChannel.close();
}
}

ssh password-less

pre

一台client机器A,一台remote机器B
你要从A机器无密码登陆到B,都是root用户

A机器

home目录下面执行

1
ssh-keygen -t rsa

可以看到在/root/.ssh下面生成三个文件

B机器

1
2
3
cd ~
mkdir /root/.ssh/
touch /root/.ssh/authorized_keys

然后把A机器的/root/.ssh/id_rsa.pub的内容copy到B机器的/root/.ssh/authorized_keys里面

修改权限

1
2
chmod 700 /root/.ssh/
chmod 600 /root/.ssh/authorized_keys

test

从A机器上面执行ssh root@192.168.77.132, 192.168.77.132是B机器的ip地址

ref

https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys-on-centos7

hostname设置

hostnamectl set-hostname ‘k8smaster’
这样设置后仅仅/etc/hostname里面有了

/etc/hosts里面依然要设置,否则ssh k8smaster依然不work, k8smaster是本机名

如果采用clone vm的方式搭建集群的话,clone后需要重新设置hostname,etc/hosts还有固定ip(/etc/sysconfig/network-script/ifcfg-xxx)

最后的结果是/etc/hostname里面各自的ip,/etc/hosts里面三个机器一样的,包括windows就是4个机器一样的

Spark Client和Cluster两种运行模式的工作流程

伪分布式搭建

  • client mode: In client mode, the driver is launched in the same process as the client that submits the application..也就是说在Client模式下,Driver进程会在当前客户端启动,客户端进程一直存在直到应用程序运行结束。
  • cluster模式:In cluster mode, however, the driver is launched from one of the Worker processes inside the cluster, and the client process exits as soon as it fulfills its responsibility of submitting the application without waiting for the application to finish.也就是说,在cluster模式下,Driver进程将会在集群中的一个worker中启动,而且客户端进程在完成自己提交任务的职责后,就可以退出,而不用等到应用程序执行完毕

reference

https://blog.csdn.net/SummerMangoZz/article/details/72627518