1 |
$("span").each(function(k, v) { arr = $(v).html().match(/c_level=C.?/); if(arr && arr.length>0) console.log(arr[0]);}) |
DevOps
1 |
$("span").each(function(k, v) { arr = $(v).html().match(/c_level=C.?/); if(arr && arr.length>0) console.log(arr[0]);}) |
总是需要写一些transform放在hive上也挺麻烦,尤其这个transform还需要复杂的配置文件或者是访问IP首先等情况,还不见得能跑通,于是,我就发明了一个万能的transform:
1 |
hive -e "select transform(1) using 'nc 10.210.227.25 1234'" |
只需要在自己喜欢的机器上执行命令行程序就行,使用nc来做这个万能的transform,然而,自己的程序总是需要listen一个端口是不是也很麻烦,其实不难:
办法1:
使用 nc -l 10.210.227.25 1234 -e “your-command”
办法2: 如果你的nc版本太低,还不支持-e
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 31 32 33 34 35 36 37 38 39 40 41 |
package main import ( "flag" "net" "os" "os/exec" "strings" ) func main() { addr := flag.String("addr", ":1234", "[host]:port") cmdline := flag.String("cmd", "", "command") flag.Parse() command := strings.SplitN(*cmdline, ",,", -1) cmdName := command[0] args := command[1:] l, err := net.Listen("tcp", *addr) if err != nil { println(err.Error()) return } for { c, err := l.Accept() if err != nil { break } cmd := exec.Command(cmdName, args...) cmd.Stderr = os.Stderr cmd.Stdout = c cmd.Stdin = c go func() { if err := cmd.Run(); err != nil { println(err.Error()) } _ = c.Close() }() } } |
把这个编译一下,类似于nc的作用
注意:
使用transform时要注意:
1 |
hive -e "select transform(1) using 'nc 10.210.227.25 1234' from TableA limit 10" |
虽然这了有limit 10 ,你的transform干的可能不是10个的活儿,哪怕这个table只有一个file,可能和执行这个任务用到的机器数量有关;从这个角度来看,hive还不够聪明;
可能需要自己优化一下:
1 |
hive -e "select transform(1) using 'nc 10.210.227.25 1234' from (select * from TableA limit 10) a " |
transform 只能靠进程数量提高效率,没法在进程内并发?这个不担心乱序?
可以设置reducer的数量来限制并发。
transform的输出格式:
If there is no AS clause after USING my_script, Hive assumes that the output of the script contains 2 parts: key which is before the first tab, and value which is the rest after the first tab. Note that this is different from specifying AS key, value because in that case, value will only contain the portion between the first tab and the second tab if there are multiple tabs.
如果transform子句的using 后面没有as子句:
则输出被视为以第一个tab为分隔的两列,第一列是key,第二列是value;如果输出中没有tab,则整行都是第一列,第二列就是NULL;如果输出中有tab,则第一个tab之前的是第一列,第一个tab以后的都视为第二列
如果transform子句的using 后面有as子句:
则按照tab分隔视为多列
参考:
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Transform
github上有不少关于规则引擎的项目,其中.net java 的比较多,go的就非常少。
https://github.com/topics/rules-engine
json的:
https://github.com/CacheControl/json-rules-engine
这个只是key op value 是否超过定义的规则
https://github.com/mithunsatheesh/node-rules
c#:
https://github.com/microsoft/RulesEngine
这个是编排工作流的
java:
https://github.com/selwynshen/nics-easy-rules
这里的思想可以看看
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "name": "transaction minimum", "priority": 3, "on" : true, "condition": function(R) { R.when(this.transactionTotal < 500); }, "consequence": function(R) { this.result = false; R.stop(); } } |
这个的特点是,可以直接在规则中定义函数; 这个适用于外包软件中的定制开发
通常情况下,我们不必使用电压表和电流表; 直接使用探针就行了。
汉字乱码分很多种情况,自从计算机进入中国就从来没有间断过,本次只讨论其中一种情况。
windows上启动虚拟机的时候,我们在任务管理器中看不到一个占用很大内存的进程(就是虚拟机进程),但是linux上启动虚拟机是可以看到这样的虚拟机进程的。
为什么呢?
有没有工具可以查看到虚拟机分配走的这部分内存呢?
有:vmmap
参考:https://serverfault.com/questions/19935/virtual-machine-memory-usage-not-appearing-in-taskmanager
yarn中的资源调度:
参考: https://blog.51cto.com/14048416/2342195
nodemanager要执行的脚本如下:
1 2 3 4 5 6 7 8 9 10 |
ll /tmp/hadoop-root/nm-local-dir/usercache/root/appcache/application_1576057255094_0007/container_1576057255094_0007_01_000003/ total 132 -rw-r--r-- 1 root root 129 Dec 12 04:15 container_tokens -rwx------ 1 root root 723 Dec 12 04:15 default_container_executor.sh -rwx------ 1 root root 669 Dec 12 04:15 default_container_executor_session.sh lrwxrwxrwx 1 root root 105 Dec 12 04:15 job.jar -> /tmp/hadoop-root/nm-local-dir/usercache/root/appcache/application_1576057255094_0007/filecache/10/job.jar -rw-r----- 1 root root 117057 Dec 12 04:15 job.xml -rwx------ 1 root root 3571 Dec 12 04:15 launch_container.sh lrwxrwxrwx 1 root root 64 Dec 12 04:15 sum.sh -> /tmp/hadoop-root/nm-local-dir/usercache/root/filecache/14/sum.sh drwx--x--- 2 root root 6 Dec 12 04:15 tmp |
default_container_executor.sh ==调起===> default_container_executor_session.sh ===调起===> launch_container.sh ===> 调起 ===> org.apache.hadoop.mapred.YarnChild
这里的脚本都是临时生成的,从进程上来看,YarnChild 的父进程是 default_container_executor.sh 而不是 launch_container.sh,是因为从default_container_executor.sh 到 org.apache.hadoop.mapred.YarnChild 的中间的所有“调起”,都使用的是exec,并不fork新的进程,也没有新的进程ID,以至于 org.apache.hadoop.mapred.YarnChild 的父进程就是default_container_executor.sh
(MRAppMaster和YarnChild的诞生方式差不多,都是nodemanager直接生出来的),所以所,MRAppMaster是一个临时的进程
NameNode: 只有在name节点上存在,只有一个进程。
DataNode: 只存在于数据节点上,每个数据节点有且只有一个这样的常住进程,负责该节点上数据的存取维护操作。
NodeManger:
ResourceMange: