大数据重要操作

Shell脚本

1、日期格式化
DT=`date -d'-1 day' +%Y-%m-%d`
echo $DT
2021-03-04
2、if判断 $1 $2 是参数
if [ $1 -eq 0 ] 
then echo '1'
else echo '2'
fi
if [[ $1 && $2 ]] // 两个参数

3、单引号(强制字符化),双引号(可以$引用变量),漂号(会被作为命令执行)的区别
[root@dream1 ~]# n=3
[root@dream1 ~]# echo '$n'
$n
[root@dream1 ~]# echo "$n"
3
[root@dream1 ~]# echo `$n`
-bash: 3: command not found
4、shell脚本中,配置环境变量
export HIVE_HOME=/opt/apps/hive
5、命令操作替换jar包中的文件:
显示jar中的文件列表:   jar  -tvf  xx.jar
解压jar中的指定文件:   jar  -xvf  xx.jar  yy.properties
更新jar中的指定文件:   jar  -uvf  xx.jar  yy.properties


端口

hadoop

namenode 9000/8020(看配置)

kafka

broker 9092

zookeeper

2181

hbase

regionserver 16010

case class

package jn.ws.util

import jn.ws.bean.LogBean
import org.apache.spark.sql.Row

/**
 * row => bean
 */
object EtlUtils {
  def row2Logbean(row: Row): LogBean = {
    row match {
      case Row(
        account: String
        , appId: String
        , appVersion: String
        , carrier: String
      ) =>
        LogBean(
          account
          , appId
          , appVersion
          , carrier
        )
      case _ => null
    }
  }
}


pt.map(EtlUtils.row2Logbean)

frame.rdd.map {
      case Row(
        repAdviceDealMethod: String,
        repAdviceTitle: String,
        repAdviceNumberOther: Int
      ) => Advice(
        repAdviceDealMethod,
        repAdviceTitle,
        repAdviceNumberOther
      )
      case _ => null
}

java -cp 如何依赖外部jar包


 在线分析平台

                       

布隆过滤器

val filter = new BloomFilter(200000000, 4, 1)
// 字典数据
for(id <- hisIds){
  filter.add(new Key(id.getBytes()))
}
// 广播
val bc = spark.sparkContext.broadcast(filter)
val res = log.map(s=>{
  val f = bc.value
  var isnew = 1
  // 查询是否存在
  if(f.membershipTest(new Key(s.getBytes()))) isnew = 0
}

经纬度计算 GeoHash,相同区域内根据lng,lat和GeoHash方法得出的结果相同

<dependency>

<groupId>ch.hsr</groupId>

<artifactId>geohash</artifactId>

<version>1.3.0</version>

</dependency>

GeoHash.geoHashStringWithCharacterPrecision(lat,lng,5)


spark广播变量

val dbByte = spark.sparkContext.broadcast(db2Bin) // 发送广播变量

val db = dbByte.value // 读取广播变量


Ip2Region,根据ip获取省市(无法获取区)

<dependency>

<groupId>org.lionsoul</groupId>

<artifactId>ip2region</artifactId>

<version>1.7.2</version>

</dependency>

val searcher = new DbSearcher(new DbConfig(), db)

val block = searcher.memorySearch(ip).toString


保存、读取parquet文件

resGeo.write.parquet("dataware/data/geo")

spark.read.parquet("dataware/data/geo")

按照指定分区 生成paquet文件

frame.write.partitionBy("provincename","cityname").parquet(parquetPath)


设置parquet的压缩格式

val config = Map[String,String](
  "spark.serializer" -> classOf[KryoSerializer].getName,
  "spark.sql.parquet.compression.codec" -> "snappy"
)

创建dataSet 一般模拟数据较为常用 seq需要引入

import spark.implicits._

val dt: Dataset[String] = spark.createDataset(Seq("60.208.118.18", "60.108.118.18", "60.215.77.35"))


spark读取资源目录

props.load(GeoHashDict.getClass.getClassLoader.getResourceAsStream("db.properties"))


 saprk加载配置文件

方式一

package com.ws.conf

import java.io.InputStream
import java.util.Properties

object ConfigHelper {
  val application = new Properties()
  val config: InputStream = ConfigHelper.getClass.getClassLoader.getResourceAsStream("application.properties")
  application.load(config)


  val master: String = application.getProperty("app.comm.master")

  val jdbc_driver: String = application.getProperty("app.mysql.driver")
  val jdbc_url: String = application.getProperty("app.mysql.url")
  val jdbc_username: String = application.getProperty("app.mysql.username")
  val jdbc_password: String = application.getProperty("app.mysql.password")

  val properties = new Properties()
  properties.setProperty("driver",jdbc_driver)
  properties.setProperty("user",jdbc_username)
  properties.setProperty("password",jdbc_password)

}

方式二 采用typesafe包的ConfigFacory

<dependency>
    <groupId>com.typesafe</groupId>
    <artifactId>config</artifactId>
    <version>1.3.0</version>
</dependency>
package com.ws.conf

import java.util.Properties

import com.typesafe.config.ConfigFactory

object ConfigHelper {
  private lazy val application = ConfigFactory.load()
  val master: String = application.getString("app.comm.master")

  val jdbc_driver: String = application.getString("app.mysql.driver")
  val jdbc_url: String = application.getString("app.mysql.url")
  val jdbc_username: String = application.getString("app.mysql.username")
  val jdbc_password: String = application.getString("app.mysql.password")

  val properties = new Properties()
  properties.setProperty("driver",jdbc_driver)
  properties.setProperty("user",jdbc_username)
  properties.setProperty("password",jdbc_password)

}

spark读取hdfs


spark读取mysql

val props = new Properties() props.load(GeoHashDict.getClass.getClassLoader.getResourceAsStream("db.properties"))

val dataFrame = spark.read.jdbc("jdbc:mysql://dream3:3306/realtimedw?useUnicode=true&characterEncoding=utf8", "t_md_areas", props)


spark自定义函数的使用

方式一

import org.apache.spark.sql.functions._

val geoMap: UserDefinedFunction = udf((lng:Double, lat:Double) => {

     GeoHash.geoHashStringWithCharacterPrecision(lat,lng,5)

})

val resGeo: DataFrame = res.select('province, 'city, 'region, geoMap('lng, 'lat) as "geohash")

方式二


DataSet转DataFrame

val DataFrame = dataset.toDF("ip", "region")

创建dataFrame


spark读取csv文件指定schema,默认都是string

val schema = new StructType()
  .add("countid", DataTypes.StringType)
  .add("deviceid", DataTypes.StringType)
  .add("sessionid", DataTypes.StringType)
  .add("ts", DataTypes.LongType)
val logdf: DataFrame = spark.read.option("header",true).schema(schema).csv("dataware/data/idBind/day1/event_app_action_log")

相对路径使用

val logdf: DataFrame = spark.read.schema(schema).csv("dataware/data/idBind/event_app_action_log")


sqoop迁移注意事项

Hive报错

 hive -hiveconf hive.root.logger=DEBUG,console

进入hive命令行,执行报错的语句


hive本地模式开启

hive.exec.mode.local.auto

false

让Hive确定是否自动启动本地模式运行

hive.exec.mode.local.auto.inputbytes.max

134217728(128MB)

当第一个参数为true时,输入字节小于此值时才能启动本地模式

hive.exec.mode.local.auto.input.files.max

4

当一个参数为true时,任务个数小于此值时才能启动本地模式

hive> SET hive.exec.mode.local.auto=true;
hive> SET hive.exec.mode.local.auto.inputbytes.max=50000000;
hive> SET hive.exec.mode.local.auto.input.files.max=5;

hiveserver2 的默认运行jvm 最多为256M 复杂的mr程序会报错无法执行,

修改hive-config.sh 调整Jvm参数

hive full join

hive explode 行转列

select(explode(array(did,uid)) as ids) from xx


spark 整合hive


hive desc 获取建表语句和表结构

show create table app_log; // 获取建表语句


hive时间戳转换

注意 hive中的时间戳是精确到秒的,而我们的代码中一般是精确到毫秒的,所以处理我们的时间戳需要除以1000在运算

0: jdbc:hive2://dream4:10000> select unix_timestamp(); 
+-------------+--+
|     _c0     |
+-------------+--+
| 1614832733  |
+-------------+--+
1 row selected (0.06 seconds)
0: jdbc:hive2://dream4:10000> select from_unixtime(1614832638,'yyyy-MM-dd');
+-------------+--+
|     _c0     |
+-------------+--+
| 2021-03-04  |
+-------------+--+
1 row selected (0.056 seconds)
0: jdbc:hive2://dream4:10000> 

insert 指定分区

spark.sql(
  """
    |insert into ipbind(deviceid,countid,ts,score) partition(dt='2020-03-08')
    |select
    | deviceid,countid,min(ts) ts,count(distinct sessionid) * 100 as score
    |from
    | logs
    |group by
    | deviceid,countid
    |""".stripMargin)

创建表指定分区

create table dwd17.idbind(deviceid string,accountid string,ts bigint,score double) partitioned by (dt string);


导入数据指定分区

load data local inpath '/root/rng.11' into table test.act_range partiton('2020-10-11')


hive 高阶聚合函数 cube 多维立方体

With cube(所有维度自由组合)

grouping sets(按照指定维度组合)


一个字段join两个字段,两列合成一列处理

select explode(array(deviceid,account)) as ids from idbind;

 Permission denied: user=Wsong, access=WRITE, inode=


启动flume

bin/flume-ng agent -c conf/ -f agentconf/yiee_log.properties -n a1  -Dflume.root.logger=DEBUG,console


删除处于ACCEPTED状态的任务


for i in  `yarn application  -list | grep -w  ACCEPTED | awk '{print $1}' | grep application_`; do yarn  application -kill $i; done


spark-yarn的资源配置

yarn的nodemanager的 容器 的工作目录


// 模式匹配

val Array(bzipPath:String,parquetPath:String) = args


隐式转换

package com.ws.etl.bean

class RichString(str: String) {
  // 定义方法
  def toRichInt: Int = {
    try {
      str.toInt
    } catch {
      case _: Exception => 0
    }
  }
  def toRichDouble: Double = try {
    str.toDouble
  } catch {
    case _:Exception => 0.0
  }
}

object RichString {
  // 定义隐式转换
  implicit def string2RichString(str:String): RichString = new RichString(str)
}

导入隐式转换,然后使用

def main(args: Array[String]): Unit = {
    // 导入隐式转换
    import com.ws.etl.bean.RichString._
    val a = "10"
    // 使用隐式转换
    println(a.toRichInt-1)
}

解决caseClass 只能装22个属性

package cn.ws.bean

/**
  * scala 2.10 版本之前 caseClass 只能装22个属性,为了解决这个问题,我们可以实现Product接口解决这个问题
  */
class Psn extend Product(
			   val name: String, // 	会话标识
			   val age: Int
		   ) extends Product {
	/**
	  * @param n 角标
	  */
	override def productElement(n: Int): Any = n match {
		case 0 => name
		case 1 => age
	}

	/**
	  * 成员属性个数
	  *
	  * @return
	  */
	override def productArity: Int = 2

	/**
	  * 是否一个同一类型
	  *
	  * @param that
	  * @return
	  */
	override def canEqual(that: Any): Boolean = that.isInstanceOf[Psn]
}

object Psn {
	def apply(arr: Array[String]): Psn = new Psn(
		arr(0),
		arr(1).toInt
	)
}

spark删除文件的方法,通用于hdfs、本地环境、或其他文件系统

package com.ws.etl.utils


import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.spark.SparkContext

object FileHelper {
  /**
   * 为了解决运行环境不一定的情况下(本地 hdfs),删除文件的问题
   *
   * @param dirPath 文件路径
   * @param sc      sparkContext
   */
  def deleteDir(dirPath: String, sc: SparkContext): AnyVal = {
    // spark 集成了 hadoop,所以我们能拿到他的core-site配置文件
    val conf = sc.hadoopConfiguration
    // 根据配置文件,获取文件系统
    val system = FileSystem.get(conf)
    val path = new Path(dirPath)
    // 根据文件系统来判断文件是否存在
    if (system.exists(path)) {
      // 是否递归删除
      system.delete(path, true)
    }
  }
}

dataFrame 过滤简单写法

1、map+=  2、match case

SparkGraph

命令行创建kafka-consumer

如何指定offset:--offset,如果指定--offset之后必须指定分区号 --partition

 bin/kafka-console-consumer.sh --bootstrap-server dream1:9092,dream2:9092,dream3:9092 --topic test --offset earliest --partition 0

spark序列化及优化方式

spark默认的序列化方式是ObjectOutputStream,比较臃肿

可以指定spark的序列化方式,org.apache.spark.serializer.kryoSerializer,这个序列化方式会少一些元数据信息,但是必须要携带类的信息,因为driver端和executor端序列化、反序列化必须要携带类的属性,是哪个类,以便于反序列化。

我们可以指定kryoSerializer所需要序列化的所有类,这样就不需要带元数据信息了。

conf.registerKryoClasses(***)


scala解构赋值

val Array(today:String,yearstoday: String) = args

 xmail

yum install mailx

vi /etc/mail.rc
set from=dream1@qq.com   #(需修改)收件人显示的发件人名称,可填写你的名字等
set smtp=smtp.qq.com  #(需修改)你所使用的外部邮箱的smtp服务器地址
set smtp-auth-user=957830825@qq.com #(需修改)你所使用的外部邮箱的用户名
set smtp-auth-password=nxyvstujuxebbbjj #(需修改)你所使用的外部邮箱密码
set smtp-auth=login
测试
echo 123 | mailx -v -s "test" xxxx@qq.com

sql-client flinkcdc

# 启动flink本地集群
${FLINK_HOME}/bin/start-cluster.sh
# 启动sql-client
${FLINK_HOME}/bin/sql-client.sh
# 需要往flink lib中放入flink-cdc.jar
# 执行完成后 看flink本地模式的webui,http://xxx:8081/#/overview

# 来源脚本1,cdc字典流
CREATE TABLE cdc_dict (
        id STRING,              
  		name STRING,               
  		age BIGINT,             
  		create_time timestamp,               
  		PRIMARY KEY(id) NOT ENFORCED   ) WITH (   
    'connector' = 'mysql-cdc',  
     'hostname' = 'xxxx',  
     'port' = '3306',   
    'username' = 'root',  
     'password' = 'xxxx',  
     'database-name' = 'dwd',   
    'table-name' = 'cdc_dict'  
 );
# 来源脚本1,kafka主流,包含sasl配置
create table cdc_main ( 
  id STRING,
  addr STRING
)
with (
'connector' = 'kafka',
'topic' = 'flink_test',
'properties.bootstrap.servers' = 'xxxx:6667', 
'properties.group.id' = 'park_test_group',
'scan.startup.mode' = 'latest-offset',
'value.format'='json',
'value.json.fail-on-missing-field' = 'false',
'value.json.ignore-parse-errors' = 'true','properties.security.protocol' = 'SASL_PLAINTEXT','properties.sasl.mechanism' = 'PLAIN','properties.sasl.jaas.config' ='org.apache.kafka.common.security.plain.PlainLoginModule required  username="admin" password="Dmp@xx";');
-- 去向脚本
CREATE TABLE cdc_res (  
     id STRING, 
      name STRING, 
      age BIGINT,  
     create_time timestamp, 
      addr STRING, 
      PRIMARY KEY(id) NOT ENFORCED  
 ) WITH ( 
    'connector' = 'jdbc', 
    'url' = 'jdbc:mysql://xxxx:3306/dwd?characterEncoding=UTF-8',  
   'table-name' = 'cdc_res',  
   'username' = 'root', 
    'password' = 'xxxx' 
);
# 操作脚本
insert into cdc_res(id,name,age,addr) select m.id,d.name,d.age,m.addr from  cdc_main m left join cdc_dict d on d.id=m.id;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值