sparkStreaming是以连续bathinterval为单位,进行bath计算,在流式计算中,如果我们想维护一段数据的状态,就需要持久化上一段的数据,sparkStreaming提供的MapwithState函数,用于更新数据状态。

例子:(更新用户当前的操作状态)
1:定义用户会话类
package com.streamkafka.user_state_update

import org.omg.CORBA.UserException

/**
* userNo:用户账号
* userName:用户名称
* userOperation:用户的操作 枚举
* userIsVIP:用户是否是会员 枚举
*/
class UserSession (userNO:String,userName:String,userOperation:String,userIsVIP:Int) extends Serializable{ var userNo="";
var user_name="";
var user_operation="";
var user_vip=false; /**
* 如果要在构造方法里调用其他方法,需要在构造方法的第一行调用构造方法
*/
def userTrans(userNO:String,user_Name:String,userOperation:Int,userIsVIP:Int){
//this(userNO,user_Name,userOperation.toString(),userIsVIP);
userNo=userNO;
user_name=user_Name;
this.operationTran(userOperation.toString())
this.isVipTran(userIsVIP);
}
//定义无参的构造方法
def this()={
this("","","",);
}
def operationTran(userOp:String){
if(userOp.equals(UserEnum.login)){
user_operation="login";
}
if(userOp.equals(UserEnum.loginOut)){
user_operation="loginOut";
}
if(userOp.equals(UserEnum.clickNextPage)){
user_operation="clickNextPage";
}
if(userOp.equals(UserEnum.clickPrePage)){
user_operation="clickPrePage";
}
if(userOp.equals(UserEnum.createUser)){
user_operation="createUser";
}
}
def isVipTran(userIsVIP:Int){
if(userIsVIP==UserEnum.Yvip){
user_vip=true;
}
if(userIsVIP==UserEnum.Nvip){
user_vip=false;
}
}
@Override
def toStrings:String= {
return "UserSession [param: userNo("+userNo+"),userName("+user_name+"),userOperation("+user_operation+"),user("+user_vip+")]";
}
}

2:定义状态枚举类

package com.streamkafka.user_state_update

import java.io.Serializable

object  UserEnum extends Serializable{
//operation 枚举
val login="";//登录操作
val loginOut="";//退出操作
val clickNextPage="";//点击下一页操作
val clickPrePage="";//点击上一页操作
val createUser="";//创建用户操作
//是否是会员 枚举
val Yvip=;
val Nvip=;
}

3:定义生产者(生产者类是使用java写的)

package com.streamkafka.user_state_update;

import java.io.Serializable;
import java.util.Properties;
import java.util.Random; import org.apache.commons.lang.math.RandomUtils;
import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata; /**
* 用户信息的格式
* userNo:用户账号 (数字+字母 长度:5)
* userName:用户名称 (汉字)
* userOperation:用户的操作 枚举 (数字:0,1,2,3,5)
* userIsVIP:用户是否是会员 枚举 (0,,1)
* @author a
*/
public class UserInfiProducer extends Thread implements Serializable{
private String topic="test";
private String userNo="userId-9iVEYecP";
private String userName="zhangxs";
private int userOper=;
private int isvip=;
private String message="";
Properties props=null;
RandomUtils rand=new RandomUtils();
Random r=new Random();
private static int msgCount=;
//消费者配置
private Properties producerParam(){
props = new Properties();
props.put("bootstrap.servers", "192.168.99.xxx:9092");//kafka的服务器ip
props.put("zk.connect", "192.168.99.143:2181");
props.put("acks", "all");
props.put("retries", );
props.put("batch.size", );
props.put("linger.ms", );
props.put("buffer.memory", );
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
return props;
}
//生产用户消息
private String producerInfo(){
StringBuffer mess=new StringBuffer();
int oper=r.nextInt();//随机产生用户的操作
if(!=oper){
userOper=oper;
}
isvip=r.nextInt();//用户是否是会员
mess.append(userNo).append("|")
.append(userName).append("|")
.append(String.valueOf(userOper)).append("|")
.append(String.valueOf(isvip));
return mess.toString();
}
KafkaProducer kp=new KafkaProducer(producerParam());
private void sendMsg(String message){
//生产者消息配置参数
Properties proper=this.producerParam();
//回调函数
Callback c=new Callback() { @Override
public void onCompletion(RecordMetadata paramRecordMetadata, Exception paramException) {
// TODO Auto-generated method stub
System.out.println("topic:"+paramRecordMetadata.topic());
System.out.println("partition:"+paramRecordMetadata.partition());
if(null!=paramException){
System.out.println("getMessage:"+paramException.getMessage());
}
}
};
//创建消息发送器
ProducerRecord<String,String> precord=new ProducerRecord<String,String>(topic, message);
//发送消息
kp.send(precord, c);
} @Override
public void run() {
while(true){
try {
message=producerInfo();
System.out.println("producer:"+message);
sendMsg(message);
System.out.println("message send success");
msgCount++;
System.out.println("成功发送【"+msgCount+"】消息");
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
public static void main(String[] args) {
UserInfiProducer userPord=new UserInfiProducer();
Thread thread=new Thread(userPord);
thread.start();
}
}

4:定义消费者

package com.streamkafka.user_state_update

import org.apache.spark.streaming.kafka010.KafkaUtils
import org.apache.spark.streaming.StreamingContext
import org.apache.spark.SparkConf
import org.apache.spark.streaming.Seconds
import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistent
import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe
import org.apache.kafka.common.serialization.StringDeserializer
import org.apache.spark.streaming.dstream.DStream
import org.apache.commons.logging.LogFactory
import org.apache.commons.logging.Log
import scala.actors.threadpool.ExecutorService
import scala.actors.threadpool.Executors
import org.apache.spark.streaming.State
import org.apache.spark.streaming.StateSpec
import org.apache.spark.streaming.Time object UserInfoConsumer extends Serializable {
var logs = LogFactory.getLog(UserInfoConsumer.getClass);
def main(args: Array[String]): Unit = {
/* val threadPool:ExecutorService=Executors.newFixedThreadPool(5)
threadPool.execute(new ConsumerProcess())*/
var cc = new ConsumerProcess();
cc.resoleMethod(); }
class ConsumerProcess extends Serializable {
def resoleMethod() {
var conf = new SparkConf();
conf.setMaster("spark://192.168.99.xxx:7077").setAppName("user_state_update");
var ssc = new StreamingContext(conf, Seconds());//创建sparkContext,这是sparkStreaming的入口
var topic = Array("test");
ssc.checkpoint(".");
var kafkaParams = Map(
//建立初始链接到kafka的服务器,这个可以是动态的所以不需要已下载配置完所有的服务器 "192.168.99.xxx:9092,anotherhost:9092"
"bootstrap.servers" -> "192.168.99.xxx:9092",
//反序列化器类实现了串并转换器接口的关键。 新的消费者配置
"key.deserializer" -> classOf[StringDeserializer],
//反序列化器类值,实现了串并转换器接口。 新的消费者配置
"value.deserializer" -> classOf[StringDeserializer],
//这是一个唯一的标识,用来标识这个消费者时属于哪个消费者组 。 新的消费者配置
"group.id" -> "user-consumer-group1",
//
"auto.offset.reset" -> "latest",
//true 定期在后台提交
"enable.auto.commit" -> (false: java.lang.Boolean))
//println("接受到的消息【"+count+"】")
//Subscribe 指定订阅的主题和配置
var dStream = KafkaUtils.createDirectStream(ssc, PreferConsistent, Subscribe[String, String](topic, kafkaParams));
dStream.foreachRDD(rdd => {
var user: UserSession = new UserSession();
rdd.foreach(f => {
var msgStr = f.value().split("\\|");//获取消息体
println("usreNo:" + msgStr())
//对消息进行解析,并封装成userSession
if ( == msgStr.length) {
print("组装userSession")
user.userTrans(msgStr().toString(), msgStr().toString(), msgStr().toInt, msgStr().toString().toInt)
} else {
print("消息格式不符合定义!!!")
}
//打印组装后的userInfo
println("userInfo:" + user.toStrings);
})
//更新用户的状态
})
     
//更新用户状态的函数
var mapWithStateMethod = (userState: String, one: Option[Int], state: State[Int]) => {
var stateInt = userState.toInt;
var userM = new UserSession();
userM.operationTran(stateInt.toString());
//返回用户当前状态和对应的枚举
var output=(userM.user_operation,stateInt);
println("当前用户的状态为:" + userM.user_operation)
state.update(stateInt);
output
} var mapState = dStream.map(x => (x.value().split("\\|")(), ));
var userState = mapState.mapWithState(StateSpec.function(mapWithStateMethod);
println("userStatePrint:" + userState.print());
print("=============================================================================")
ssc.start();
ssc.awaitTermination();
}
/* override def run(){
while(true){
print("进入run方法.................");
resoleMethod();
ssc.start();
ssc.awaitTermination();
Thread.sleep(5000L);
}
}*/
}
}

sparkStreaming的mapWithState函数【案例二】的更多相关文章

  1. python第十四课--排序及自定义函数之自定义函数(案例二)

    案例二: python中定义有/无返回值的函数,演示python没有函数重载这一说 需求:自定义函数:计算两个整数的和值两个原则:1).有没形参有,两个 2).有没返回值可有可无 def my_sum ...

  2. python第十四课--排序及自定义函数之案例二:冒泡排序

    案例二:冒泡排序 lt1=[45,12,56,-32,-3,44,75,-22,100] print('排序前:'+str(lt1)) 自定义函数:实现冒泡排序(升序)原则:1).有没有形参?有,接受 ...

  3. 第1节 flume:15、flume案例二,通过自定义拦截器实现数据的脱敏

    1.7.flume案例二 案例需求: 在数据采集之后,通过flume的拦截器,实现不需要的数据过滤掉,并将指定的第一个字段进行加密,加密之后再往hdfs上面保存 原始数据与处理之后的数据对比 图一  ...

  4. Javascript常用方法函数收集(二)

    Javascript常用方法函数收集(二) 31.判断是否Touch屏幕 function isTouchScreen(){ return (('ontouchstart' in window) || ...

  5. Lua函数之二

    Lua函数之二 Lua中函数的两个重要特性: 1.函数和其他类型(如number.string)一样,可以存放在变量中,也可以存放在table中,可以作为函数的参数,还可以作为函数的返回值. 2.嵌套 ...

  6. Android实训案例(二)——Android下的CMD命令之关机重启以及重启recovery

    Android实训案例(二)--Android下的CMD命令之关机重启以及重启recovery Android刚兴起的时候,着实让一些小众软件火了一把,切水果,Tom猫,吹裙子就是其中的代表,当然还有 ...

  7. day 16 - 2 内置函数(二)练习

    内置函数(二)练习 1.用 map 来处理字符串列表,把列表中所有人都变成 sb,比方 alex_sbname=['alex','wupeiqi','yuanhao','nezha'] name=[' ...

  8. day 16 - 1 内置函数(二)

    内置函数(二) reversed()  返回一个反向的迭代器 k = [1,2,3,4,5] k.reverse() #反转 print(k) k = [1,2,3,4,5] k2 = reverse ...

  9. [C++ Primer Plus] 第7章、函数(一)程序清单——递归,指针和const,指针数组和数组指针,函数和二维数组

    程序清单7.6 #include<iostream> using namespace std; ; int sum_arr(int arr[], int n);//函数声明 void ma ...

随机推荐

  1. 牛客网练习赛18 A 【数论/整数划分得到乘积最大/快速乘】

    链接:https://www.nowcoder.com/acm/contest/110/A 来源:牛客网 题目描述 这题要你回答T个询问,给你一个正整数S,若有若干个正整数的和为S,则这若干的数的乘积 ...

  2. 「JXOI2018」游戏

    注意输出的应该是 所有方案的和,,而不是期望. 我们不妨把依赖关系建图,可以发现 所有没有入度的点都被查水表了一次 是 游戏结束的 充要条件. 于是我们只需要知道有多少没有入度的点,然后再排列算一算就 ...

  3. 【bzoj1566】【管道取珠】竟然是dp题(浅尝ACM-E)

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=61891436 向大(hei)佬(e)势力学(di ...

  4. django10 使用自定义标签配置说明

    1).在app目录下建目录templatetags[不可改名]目录,然后在该目录下建一个空的__init__.py 2).mytags.py 在templatetags下建一个mytags.py,添加 ...

  5. python定时执行方法

    1  time.sleep import time for i in range(5): print(i) time.sleep(10) 2 用shed import time import sche ...

  6. 为什么代理属性设置成assign为了防止生成保留环来

    循环引用 全部的引用计数系统, 都存在循环应用的问题, 比如以下的引用关系: 1. 对象a创建并引用到了对象b 2. 对象b创建并引用到了对象c 3. 对象c创建并引用到了对象b 这时候b和c的引用计 ...

  7. util.string.js

    ylbtech-JavaScript-util: util.string.js 字符串处理工具 1.A,JS-效果图返回顶部   1.B,JS-Source Code(源代码)返回顶部 1.B.1, ...

  8. Http协议三次握手过程

    Http协议三次握手过程   TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: ...

  9. Solr 6.6.0 ERROR: Port 8983 is already being used by another process.

    在目录D:\work\Solr\solr-6.6.0\bin下打开命令框: 输入:solr -e dih报错:ERROR: Port 8983 is already being used by ano ...

  10. 跟我一起透彻理解template模板模式

    #include <iostream> using namespace std; //template模式. class Base { public: void DealWhat() { ...