前端技术
HTML
CSS
Javascript
前端框架和UI库
VUE
ReactJS
AngularJS
JQuery
NodeJS
JSON
Element-UI
Bootstrap
Material UI
服务端和客户端
Java
Python
PHP
Golang
Scala
Kotlin
Groovy
Ruby
Lua
.net
c#
c++
后端WEB和工程框架
SpringBoot
SpringCloud
Struts2
MyBatis
Hibernate
Tornado
Beego
Go-Spring
Go Gin
Go Iris
Dubbo
HessianRPC
Maven
Gradle
数据库
MySQL
Oracle
Mongo
中间件与web容器
Redis
MemCache
Etcd
Cassandra
Kafka
RabbitMQ
RocketMQ
ActiveMQ
Nacos
Consul
Tomcat
Nginx
Netty
大数据技术
Hive
Impala
ClickHouse
DorisDB
Greenplum
PostgreSQL
HBase
Kylin
Hadoop
Apache Pig
ZooKeeper
SeaTunnel
Sqoop
Datax
Flink
Spark
Mahout
数据搜索与日志
ElasticSearch
Apache Lucene
Apache Solr
Kibana
Logstash
数据可视化与OLAP
Apache Atlas
Superset
Saiku
Tesseract
系统与容器
Linux
Shell
Docker
Kubernetes
[分布式计算环境中数据分片与压缩效果权衡 ]的搜索结果
这里是文章列表。热门标签的颜色随机变换,标签颜色没有特殊含义。
点击某个标签可搜索标签相关的文章。
点击某个标签可搜索标签相关的文章。
转载文章
...ket往后台发送日志数据,在这里我们是要做基于SparkStreaming做实时在线统计。那么数据就需要放进消息系统(Kafka)中,我们的Spark Streaming应用程序就会去Kafka中Pull数据过来进行计算和消费,并把计算后的数据放入到持久化系统中(MySQL) 广告点击系统实时分析的意义:因为可以在线实时的看见广告的投放效果,就为广告的更大规模的投入和调整打下了坚实的基础,从而为公司带来最大化的经济回报。 核心需求: 1、实时黑名单动态过滤出有效的用户广告点击行为:因为黑名单用户可能随时出现,所以需要动态更新; 2、在线计算广告点击流量; 3、Top3热门广告; 4、每个广告流量趋势; 5、广告点击用户的区域分布分析 6、最近一分钟的广告点击量; 7、整个广告点击Spark Streaming处理程序724小时运行; 数据格式: 时间、用户、广告、城市等 技术细节: 在线计算用户点击的次数分析,屏蔽IP等; 使用updateStateByKey或者mapWithState进行不同地区广告点击排名的计算; Spark Streaming+Spark SQL+Spark Core等综合分析数据; 使用Window类型的操作; 高可用和性能调优等等; 流量趋势,一般会结合DB等; Spark Core / /package com.tom.spark.SparkApps.sparkstreaming;import java.util.Date;import java.util.HashMap;import java.util.Map;import java.util.Properties;import java.util.Random;import kafka.javaapi.producer.Producer;import kafka.producer.KeyedMessage;import kafka.producer.ProducerConfig;/ 数据生成代码,Kafka Producer产生数据/public class MockAdClickedStat {/ @param args/public static void main(String[] args) {final Random random = new Random();final String[] provinces = new String[]{"Guangdong", "Zhejiang", "Jiangsu", "Fujian"};final Map<String, String[]> cities = new HashMap<String, String[]>();cities.put("Guangdong", new String[]{"Guangzhou", "Shenzhen", "Dongguan"});cities.put("Zhejiang", new String[]{"Hangzhou", "Wenzhou", "Ningbo"});cities.put("Jiangsu", new String[]{"Nanjing", "Suzhou", "Wuxi"});cities.put("Fujian", new String[]{"Fuzhou", "Xiamen", "Sanming"});final String[] ips = new String[] {"192.168.112.240","192.168.112.239","192.168.112.245","192.168.112.246","192.168.112.247","192.168.112.248","192.168.112.249","192.168.112.250","192.168.112.251","192.168.112.252","192.168.112.253","192.168.112.254",};/ Kafka相关的基本配置信息/Properties kafkaConf = new Properties();kafkaConf.put("serializer.class", "kafka.serializer.StringEncoder");kafkaConf.put("metadeta.broker.list", "Master:9092,Worker1:9092,Worker2:9092");ProducerConfig producerConfig = new ProducerConfig(kafkaConf);final Producer<Integer, String> producer = new Producer<Integer, String>(producerConfig);new Thread(new Runnable() {public void run() {while(true) {//在线处理广告点击流的基本数据格式:timestamp、ip、userID、adID、province、cityLong timestamp = new Date().getTime();String ip = ips[random.nextInt(12)]; //可以采用网络上免费提供的ip库int userID = random.nextInt(10000);int adID = random.nextInt(100);String province = provinces[random.nextInt(4)];String city = cities.get(province)[random.nextInt(3)];String clickedAd = timestamp + "\t" + ip + "\t" + userID + "\t" + adID + "\t" + province + "\t" + city;producer.send(new KeyedMessage<Integer, String>("AdClicked", clickedAd));try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} }} }).start();} } package com.tom.spark.SparkApps.sparkstreaming;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.concurrent.LinkedBlockingQueue;import kafka.serializer.StringDecoder;import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaPairRDD;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.api.java.JavaSparkContext;import org.apache.spark.api.java.function.Function;import org.apache.spark.api.java.function.Function2;import org.apache.spark.api.java.function.PairFunction;import org.apache.spark.api.java.function.VoidFunction;import org.apache.spark.sql.DataFrame;import org.apache.spark.sql.Row;import org.apache.spark.sql.RowFactory;import org.apache.spark.sql.hive.HiveContext;import org.apache.spark.sql.types.DataTypes;import org.apache.spark.sql.types.StructType;import org.apache.spark.streaming.Durations;import org.apache.spark.streaming.api.java.JavaDStream;import org.apache.spark.streaming.api.java.JavaPairDStream;import org.apache.spark.streaming.api.java.JavaPairInputDStream;import org.apache.spark.streaming.api.java.JavaStreamingContext;import org.apache.spark.streaming.api.java.JavaStreamingContextFactory;import org.apache.spark.streaming.kafka.KafkaUtils;import com.google.common.base.Optional;import scala.Tuple2;/ 数据处理,Kafka消费者/public class AdClickedStreamingStats {/ @param args/public static void main(String[] args) {// TODO Auto-generated method stub//好处:1、checkpoint 2、工厂final SparkConf conf = new SparkConf().setAppName("SparkStreamingOnKafkaDirect").setMaster("hdfs://Master:7077/");final String checkpointDirectory = "hdfs://Master:9000/library/SparkStreaming/CheckPoint_Data";JavaStreamingContextFactory factory = new JavaStreamingContextFactory() {public JavaStreamingContext create() {// TODO Auto-generated method stubreturn createContext(checkpointDirectory, conf);} };/ 可以从失败中恢复Driver,不过还需要指定Driver这个进程运行在Cluster,并且在提交应用程序的时候制定--supervise;/JavaStreamingContext javassc = JavaStreamingContext.getOrCreate(checkpointDirectory, factory);/ 第三步:创建Spark Streaming输入数据来源input Stream: 1、数据输入来源可以基于File、HDFS、Flume、Kafka、Socket等 2、在这里我们指定数据来源于网络Socket端口,Spark Streaming连接上该端口并在运行的时候一直监听该端口的数据 (当然该端口服务首先必须存在),并且在后续会根据业务需要不断有数据产生(当然对于Spark Streaming 应用程序的运行而言,有无数据其处理流程都是一样的) 3、如果经常在每间隔5秒钟没有数据的话不断启动空的Job其实会造成调度资源的浪费,因为并没有数据需要发生计算;所以 实际的企业级生成环境的代码在具体提交Job前会判断是否有数据,如果没有的话就不再提交Job;///创建Kafka元数据来让Spark Streaming这个Kafka Consumer利用Map<String, String> kafkaParameters = new HashMap<String, String>();kafkaParameters.put("metadata.broker.list", "Master:9092,Worker1:9092,Worker2:9092");Set<String> topics = new HashSet<String>();topics.add("SparkStreamingDirected");JavaPairInputDStream<String, String> adClickedStreaming = KafkaUtils.createDirectStream(javassc, String.class, String.class, StringDecoder.class, StringDecoder.class,kafkaParameters, topics);/因为要对黑名单进行过滤,而数据是在RDD中的,所以必然使用transform这个函数; 但是在这里我们必须使用transformToPair,原因是读取进来的Kafka的数据是Pair<String,String>类型, 另一个原因是过滤后的数据要进行进一步处理,所以必须是读进的Kafka数据的原始类型 在此再次说明,每个Batch Duration中实际上讲输入的数据就是被一个且仅被一个RDD封装的,你可以有多个 InputDStream,但其实在产生job的时候,这些不同的InputDStream在Batch Duration中就相当于Spark基于HDFS 数据操作的不同文件来源而已罢了。/JavaPairDStream<String, String> filteredadClickedStreaming = adClickedStreaming.transformToPair(new Function<JavaPairRDD<String,String>, JavaPairRDD<String,String>>() {public JavaPairRDD<String, String> call(JavaPairRDD<String, String> rdd) throws Exception {/ 在线黑名单过滤思路步骤: 1、从数据库中获取黑名单转换成RDD,即新的RDD实例封装黑名单数据; 2、然后把代表黑名单的RDD的实例和Batch Duration产生的RDD进行Join操作, 准确的说是进行leftOuterJoin操作,也就是说使用Batch Duration产生的RDD和代表黑名单的RDD实例进行 leftOuterJoin操作,如果两者都有内容的话,就会是true,否则的话就是false 我们要留下的是leftOuterJoin结果为false; /final List<String> blackListNames = new ArrayList<String>();JDBCWrapper jdbcWrapper = JDBCWrapper.getJDBCInstance();jdbcWrapper.doQuery("SELECT FROM blacklisttable", null, new ExecuteCallBack() {public void resultCallBack(ResultSet result) throws Exception {while(result.next()){blackListNames.add(result.getString(1));} }});List<Tuple2<String, Boolean>> blackListTuple = new ArrayList<Tuple2<String,Boolean>>();for(String name : blackListNames) {blackListTuple.add(new Tuple2<String, Boolean>(name, true));}List<Tuple2<String, Boolean>> blacklistFromListDB = blackListTuple; //数据来自于查询的黑名单表并且映射成为<String, Boolean>JavaSparkContext jsc = new JavaSparkContext(rdd.context());/ 黑名单的表中只有userID,但是如果要进行join操作的话就必须是Key-Value,所以在这里我们需要 基于数据表中的数据产生Key-Value类型的数据集合/JavaPairRDD<String, Boolean> blackListRDD = jsc.parallelizePairs(blacklistFromListDB);/ 进行操作的时候肯定是基于userID进行join,所以必须把传入的rdd进行mapToPair操作转化成为符合格式的RDD/JavaPairRDD<String, Tuple2<String, String>> rdd2Pair = rdd.mapToPair(new PairFunction<Tuple2<String,String>, String, Tuple2<String, String>>() {public Tuple2<String, Tuple2<String, String>> call(Tuple2<String, String> t) throws Exception {// TODO Auto-generated method stubString userID = t._2.split("\t")[2];return new Tuple2<String, Tuple2<String,String>>(userID, t);} });JavaPairRDD<String, Tuple2<Tuple2<String, String>, Optional<Boolean>>> joined = rdd2Pair.leftOuterJoin(blackListRDD);JavaPairRDD<String, String> result = joined.filter(new Function<Tuple2<String,Tuple2<Tuple2<String,String>,Optional<Boolean>>>, Boolean>() {public Boolean call(Tuple2<String, Tuple2<Tuple2<String, String>, Optional<Boolean>>> tuple)throws Exception {// TODO Auto-generated method stubOptional<Boolean> optional = tuple._2._2;if(optional.isPresent() && optional.get()){return false;} else {return true;} }}).mapToPair(new PairFunction<Tuple2<String,Tuple2<Tuple2<String,String>,Optional<Boolean>>>, String, String>() {public Tuple2<String, String> call(Tuple2<String, Tuple2<Tuple2<String, String>, Optional<Boolean>>> t)throws Exception {// TODO Auto-generated method stubreturn t._2._1;} });return result;} });//广告点击的基本数据格式:timestamp、ip、userID、adID、province、cityJavaPairDStream<String, Long> pairs = filteredadClickedStreaming.mapToPair(new PairFunction<Tuple2<String,String>, String, Long>() {public Tuple2<String, Long> call(Tuple2<String, String> t) throws Exception {String[] splited=t._2.split("\t");String timestamp = splited[0]; //YYYY-MM-DDString ip = splited[1];String userID = splited[2];String adID = splited[3];String province = splited[4];String city = splited[5]; String clickedRecord = timestamp + "_" +ip + "_"+userID+"_"+adID+"_"+province +"_"+city;return new Tuple2<String, Long>(clickedRecord, 1L);} });/ 第4.3步:在单词实例计数为1基础上,统计每个单词在文件中出现的总次数/JavaPairDStream<String, Long> adClickedUsers= pairs.reduceByKey(new Function2<Long, Long, Long>() {public Long call(Long i1, Long i2) throws Exception{return i1 + i2;} });/判断有效的点击,复杂化的采用机器学习训练模型进行在线过滤 简单的根据ip判断1天不超过100次;也可以通过一个batch duration的点击次数判断是否非法广告点击,通过一个batch来判断是不完整的,还需要一天的数据也可以每一个小时来判断。/JavaPairDStream<String, Long> filterClickedBatch = adClickedUsers.filter(new Function<Tuple2<String,Long>, Boolean>() {public Boolean call(Tuple2<String, Long> v1) throws Exception {if (1 < v1._2){//更新一些黑名单的数据库表return false;} else { return true;} }});//filterClickedBatch.print();//写入数据库filterClickedBatch.foreachRDD(new Function<JavaPairRDD<String,Long>, Void>() {public Void call(JavaPairRDD<String, Long> rdd) throws Exception {rdd.foreachPartition(new VoidFunction<Iterator<Tuple2<String,Long>>>() {public void call(Iterator<Tuple2<String, Long>> partition) throws Exception {//使用数据库连接池的高效读写数据库的方式将数据写入数据库mysql//例如一次插入 1000条 records,使用insertBatch 或 updateBatch//插入的用户数据信息:userID,adID,clickedCount,time//这里面有一个问题,可能出现两条记录的key是一样的,此时需要更新累加操作List<UserAdClicked> userAdClickedList = new ArrayList<UserAdClicked>();while(partition.hasNext()) {Tuple2<String, Long> record = partition.next();String[] splited = record._1.split("\t");UserAdClicked userClicked = new UserAdClicked();userClicked.setTimestamp(splited[0]);userClicked.setIp(splited[1]);userClicked.setUserID(splited[2]);userClicked.setAdID(splited[3]);userClicked.setProvince(splited[4]);userClicked.setCity(splited[5]);userAdClickedList.add(userClicked);}final List<UserAdClicked> inserting = new ArrayList<UserAdClicked>();final List<UserAdClicked> updating = new ArrayList<UserAdClicked>();JDBCWrapper jdbcWrapper = JDBCWrapper.getJDBCInstance();//表的字段timestamp、ip、userID、adID、province、city、clickedCountfor(final UserAdClicked clicked : userAdClickedList) {jdbcWrapper.doQuery("SELECT clickedCount FROM adclicked WHERE"+ " timestamp =? AND userID = ? AND adID = ?",new Object[]{clicked.getTimestamp(), clicked.getUserID(),clicked.getAdID()}, new ExecuteCallBack() {public void resultCallBack(ResultSet result) throws Exception {// TODO Auto-generated method stubif(result.next()) {long count = result.getLong(1);clicked.setClickedCount(count);updating.add(clicked);} else {inserting.add(clicked);clicked.setClickedCount(1L);} }});}//表的字段timestamp、ip、userID、adID、province、city、clickedCountList<Object[]> insertParametersList = new ArrayList<Object[]>();for(UserAdClicked insertRecord : inserting) {insertParametersList.add(new Object[] {insertRecord.getTimestamp(),insertRecord.getIp(),insertRecord.getUserID(),insertRecord.getAdID(),insertRecord.getProvince(),insertRecord.getCity(),insertRecord.getClickedCount()});}jdbcWrapper.doBatch("INSERT INTO adclicked VALUES(?, ?, ?, ?, ?, ?, ?)", insertParametersList);//表的字段timestamp、ip、userID、adID、province、city、clickedCountList<Object[]> updateParametersList = new ArrayList<Object[]>();for(UserAdClicked updateRecord : updating) {updateParametersList.add(new Object[] {updateRecord.getTimestamp(),updateRecord.getIp(),updateRecord.getUserID(),updateRecord.getAdID(),updateRecord.getProvince(),updateRecord.getCity(),updateRecord.getClickedCount() + 1});}jdbcWrapper.doBatch("UPDATE adclicked SET clickedCount = ? WHERE"+ " timestamp =? AND ip = ? AND userID = ? AND adID = ? "+ "AND province = ? AND city = ?", updateParametersList);} });return null;} });//再次过滤,从数据库中读取数据过滤黑名单JavaPairDStream<String, Long> blackListBasedOnHistory = filterClickedBatch.filter(new Function<Tuple2<String,Long>, Boolean>() {public Boolean call(Tuple2<String, Long> v1) throws Exception {//广告点击的基本数据格式:timestamp,ip,userID,adID,province,cityString[] splited = v1._1.split("\t"); //提取key值String date =splited[0];String userID =splited[2];String adID =splited[3];//查询一下数据库同一个用户同一个广告id点击量超过50次列入黑名单//接下来 根据date、userID、adID条件去查询用户点击广告的数据表,获得总的点击次数//这个时候基于点击次数判断是否属于黑名单点击int clickedCountTotalToday = 81 ;if (clickedCountTotalToday > 50) {return true;}else {return false ;} }});//map操作,找出用户的idJavaDStream<String> blackListuserIDBasedInBatchOnhistroy =blackListBasedOnHistory.map(new Function<Tuple2<String,Long>, String>() {public String call(Tuple2<String, Long> v1) throws Exception {// TODO Auto-generated method stubreturn v1._1.split("\t")[2];} });//有一个问题,数据可能重复,在一个partition里面重复,这个好办;//但多个partition不能保证一个用户重复,需要对黑名单的整个rdd进行去重操作。//rdd去重了,partition也就去重了,一石二鸟,一箭双雕// 找出了黑名单,下一步就写入黑名单数据库表中JavaDStream<String> blackListUniqueuserBasedInBatchOnhistroy = blackListuserIDBasedInBatchOnhistroy.transform(new Function<JavaRDD<String>, JavaRDD<String>>() {public JavaRDD<String> call(JavaRDD<String> rdd) throws Exception {// TODO Auto-generated method stubreturn rdd.distinct();} });// 下一步写入到数据表中blackListUniqueuserBasedInBatchOnhistroy.foreachRDD(new Function<JavaRDD<String>, Void>() {public Void call(JavaRDD<String> rdd) throws Exception {rdd.foreachPartition(new VoidFunction<Iterator<String>>() {public void call(Iterator<String> t) throws Exception {// TODO Auto-generated method stub//插入的用户信息可以只包含:useID//此时直接插入黑名单数据表即可。//写入数据库List<Object[]> blackList = new ArrayList<Object[]>();while(t.hasNext()) {blackList.add(new Object[]{t.next()});}JDBCWrapper jdbcWrapper = JDBCWrapper.getJDBCInstance();jdbcWrapper.doBatch("INSERT INTO blacklisttable values (?)", blackList);} });return null;} });/广告点击累计动态更新,每个updateStateByKey都会在Batch Duration的时间间隔的基础上进行广告点击次数的更新, 更新之后我们一般都会持久化到外部存储设备上,在这里我们存储到MySQL数据库中/JavaPairDStream<String, Long> updateStateByKeyDSteam = filteredadClickedStreaming.mapToPair(new PairFunction<Tuple2<String,String>, String, Long>() {public Tuple2<String, Long> call(Tuple2<String, String> t)throws Exception {String[] splited=t._2.split("\t");String timestamp = splited[0]; //YYYY-MM-DDString ip = splited[1];String userID = splited[2];String adID = splited[3];String province = splited[4];String city = splited[5]; String clickedRecord = timestamp + "_" +ip + "_"+userID+"_"+adID+"_"+province +"_"+city;return new Tuple2<String, Long>(clickedRecord, 1L);} }).updateStateByKey(new Function2<List<Long>, Optional<Long>, Optional<Long>>() {public Optional<Long> call(List<Long> v1, Optional<Long> v2)throws Exception {// v1:当前的Key在当前的Batch Duration中出现的次数的集合,例如{1,1,1,。。。,1}// v2:当前的Key在以前的Batch Duration中积累下来的结果;Long clickedTotalHistory = 0L; if(v2.isPresent()){clickedTotalHistory = v2.get();}for(Long one : v1) {clickedTotalHistory += one;}return Optional.of(clickedTotalHistory);} });updateStateByKeyDSteam.foreachRDD(new Function<JavaPairRDD<String,Long>, Void>() {public Void call(JavaPairRDD<String, Long> rdd) throws Exception {rdd.foreachPartition(new VoidFunction<Iterator<Tuple2<String,Long>>>() {public void call(Iterator<Tuple2<String, Long>> partition) throws Exception {//使用数据库连接池的高效读写数据库的方式将数据写入数据库mysql//例如一次插入 1000条 records,使用insertBatch 或 updateBatch//插入的用户数据信息:timestamp、adID、province、city//这里面有一个问题,可能出现两条记录的key是一样的,此时需要更新累加操作List<AdClicked> AdClickedList = new ArrayList<AdClicked>();while(partition.hasNext()) {Tuple2<String, Long> record = partition.next();String[] splited = record._1.split("\t");AdClicked adClicked = new AdClicked();adClicked.setTimestamp(splited[0]);adClicked.setAdID(splited[1]);adClicked.setProvince(splited[2]);adClicked.setCity(splited[3]);adClicked.setClickedCount(record._2);AdClickedList.add(adClicked);}final List<AdClicked> inserting = new ArrayList<AdClicked>();final List<AdClicked> updating = new ArrayList<AdClicked>();JDBCWrapper jdbcWrapper = JDBCWrapper.getJDBCInstance();//表的字段timestamp、ip、userID、adID、province、city、clickedCountfor(final AdClicked clicked : AdClickedList) {jdbcWrapper.doQuery("SELECT clickedCount FROM adclickedcount WHERE"+ " timestamp = ? AND adID = ? AND province = ? AND city = ?",new Object[]{clicked.getTimestamp(), clicked.getAdID(),clicked.getProvince(), clicked.getCity()}, new ExecuteCallBack() {public void resultCallBack(ResultSet result) throws Exception {// TODO Auto-generated method stubif(result.next()) {long count = result.getLong(1);clicked.setClickedCount(count);updating.add(clicked);} else {inserting.add(clicked);clicked.setClickedCount(1L);} }});}//表的字段timestamp、ip、userID、adID、province、city、clickedCountList<Object[]> insertParametersList = new ArrayList<Object[]>();for(AdClicked insertRecord : inserting) {insertParametersList.add(new Object[] {insertRecord.getTimestamp(),insertRecord.getAdID(),insertRecord.getProvince(),insertRecord.getCity(),insertRecord.getClickedCount()});}jdbcWrapper.doBatch("INSERT INTO adclickedcount VALUES(?, ?, ?, ?, ?)", insertParametersList);//表的字段timestamp、ip、userID、adID、province、city、clickedCountList<Object[]> updateParametersList = new ArrayList<Object[]>();for(AdClicked updateRecord : updating) {updateParametersList.add(new Object[] {updateRecord.getClickedCount(),updateRecord.getTimestamp(),updateRecord.getAdID(),updateRecord.getProvince(),updateRecord.getCity()});}jdbcWrapper.doBatch("UPDATE adclickedcount SET clickedCount = ? WHERE"+ " timestamp =? AND adID = ? AND province = ? AND city = ?", updateParametersList);} });return null;} });/ 对广告点击进行TopN计算,计算出每天每个省份Top5排名的广告 因为我们直接对RDD进行操作,所以使用了transfomr算子;/updateStateByKeyDSteam.transform(new Function<JavaPairRDD<String,Long>, JavaRDD<Row>>() {public JavaRDD<Row> call(JavaPairRDD<String, Long> rdd) throws Exception {JavaRDD<Row> rowRDD = rdd.mapToPair(new PairFunction<Tuple2<String,Long>, String, Long>() {public Tuple2<String, Long> call(Tuple2<String, Long> t)throws Exception {// TODO Auto-generated method stubString[] splited=t._1.split("_");String timestamp = splited[0]; //YYYY-MM-DDString adID = splited[3];String province = splited[4];String clickedRecord = timestamp + "_" + adID + "_" + province;return new Tuple2<String, Long>(clickedRecord, t._2);} }).reduceByKey(new Function2<Long, Long, Long>() {public Long call(Long v1, Long v2) throws Exception {// TODO Auto-generated method stubreturn v1 + v2;} }).map(new Function<Tuple2<String,Long>, Row>() {public Row call(Tuple2<String, Long> v1) throws Exception {// TODO Auto-generated method stubString[] splited=v1._1.split("_");String timestamp = splited[0]; //YYYY-MM-DDString adID = splited[3];String province = splited[4];return RowFactory.create(timestamp, adID, province, v1._2);} });StructType structType = DataTypes.createStructType(Arrays.asList(DataTypes.createStructField("timestamp", DataTypes.StringType, true),DataTypes.createStructField("adID", DataTypes.StringType, true),DataTypes.createStructField("province", DataTypes.StringType, true),DataTypes.createStructField("clickedCount", DataTypes.LongType, true)));HiveContext hiveContext = new HiveContext(rdd.context());DataFrame df = hiveContext.createDataFrame(rowRDD, structType);df.registerTempTable("topNTableSource");DataFrame result = hiveContext.sql("SELECT timestamp, adID, province, clickedCount, FROM"+ " (SELECT timestamp, adID, province,clickedCount, "+ "ROW_NUMBER() OVER(PARTITION BY province ORDER BY clickeCount DESC) rank "+ "FROM topNTableSource) subquery "+ "WHERE rank <= 5");return result.toJavaRDD();} }).foreachRDD(new Function<JavaRDD<Row>, Void>() {public Void call(JavaRDD<Row> rdd) throws Exception {// TODO Auto-generated method stubrdd.foreachPartition(new VoidFunction<Iterator<Row>>() {public void call(Iterator<Row> t) throws Exception {// TODO Auto-generated method stubList<AdProvinceTopN> adProvinceTopN = new ArrayList<AdProvinceTopN>();while(t.hasNext()) {Row row = t.next();AdProvinceTopN item = new AdProvinceTopN();item.setTimestamp(row.getString(0));item.setAdID(row.getString(1));item.setProvince(row.getString(2));item.setClickedCount(row.getLong(3));adProvinceTopN.add(item);}// final List<AdProvinceTopN> inserting = new ArrayList<AdProvinceTopN>();// final List<AdProvinceTopN> updating = new ArrayList<AdProvinceTopN>();JDBCWrapper jdbcWrapper = JDBCWrapper.getJDBCInstance();Set<String> set = new HashSet<String>();for(AdProvinceTopN item: adProvinceTopN){set.add(item.getTimestamp() + "_" + item.getProvince());}//表的字段timestamp、adID、province、clickedCountArrayList<Object[]> deleteParametersList = new ArrayList<Object[]>();for(String deleteRecord : set) {String[] splited = deleteRecord.split("_");deleteParametersList.add(new Object[]{splited[0],splited[1]});}jdbcWrapper.doBatch("DELETE FROM adprovincetopn WHERE timestamp = ? AND province = ?", deleteParametersList);//表的字段timestamp、ip、userID、adID、province、city、clickedCountList<Object[]> insertParametersList = new ArrayList<Object[]>();for(AdProvinceTopN insertRecord : adProvinceTopN) {insertParametersList.add(new Object[] {insertRecord.getClickedCount(),insertRecord.getTimestamp(),insertRecord.getAdID(),insertRecord.getProvince()});}jdbcWrapper.doBatch("INSERT INTO adprovincetopn VALUES (?, ?, ?, ?)", insertParametersList);} });return null;} });/ 计算过去半个小时内广告点击的趋势 广告点击的基本数据格式:timestamp、ip、userID、adID、province、city/filteredadClickedStreaming.mapToPair(new PairFunction<Tuple2<String,String>, String, Long>() {public Tuple2<String, Long> call(Tuple2<String, String> t)throws Exception {String splited[] = t._2.split("\t");String adID = splited[3];String time = splited[0]; //Todo:后续需要重构代码实现时间戳和分钟的转换提取。此处需要提取出该广告的点击分钟单位return new Tuple2<String, Long>(time + "_" + adID, 1L);} }).reduceByKeyAndWindow(new Function2<Long, Long, Long>() {public Long call(Long v1, Long v2) throws Exception {// TODO Auto-generated method stubreturn v1 + v2;} }, new Function2<Long, Long, Long>() {public Long call(Long v1, Long v2) throws Exception {// TODO Auto-generated method stubreturn v1 - v2;} }, Durations.minutes(30), Durations.milliseconds(5)).foreachRDD(new Function<JavaPairRDD<String,Long>, Void>() {public Void call(JavaPairRDD<String, Long> rdd) throws Exception {// TODO Auto-generated method stubrdd.foreachPartition(new VoidFunction<Iterator<Tuple2<String,Long>>>() {public void call(Iterator<Tuple2<String, Long>> partition)throws Exception {List<AdTrendStat> adTrend = new ArrayList<AdTrendStat>();// TODO Auto-generated method stubwhile(partition.hasNext()) {Tuple2<String, Long> record = partition.next();String[] splited = record._1.split("_");String time = splited[0];String adID = splited[1];Long clickedCount = record._2;/ 在插入数据到数据库的时候具体需要哪些字段?time、adID、clickedCount; 而我们通过J2EE技术进行趋势绘图的时候肯定是需要年、月、日、时、分这个维度的,所以我们在这里需要 年月日、小时、分钟这些时间维度;/AdTrendStat adTrendStat = new AdTrendStat();adTrendStat.setAdID(adID);adTrendStat.setClickedCount(clickedCount);adTrendStat.set_date(time); //Todo:获取年月日adTrendStat.set_hour(time); //Todo:获取小时adTrendStat.set_minute(time);//Todo:获取分钟adTrend.add(adTrendStat);}final List<AdTrendStat> inserting = new ArrayList<AdTrendStat>();final List<AdTrendStat> updating = new ArrayList<AdTrendStat>();JDBCWrapper jdbcWrapper = JDBCWrapper.getJDBCInstance();//表的字段timestamp、ip、userID、adID、province、city、clickedCountfor(final AdTrendStat trend : adTrend) {final AdTrendCountHistory adTrendhistory = new AdTrendCountHistory();jdbcWrapper.doQuery("SELECT clickedCount FROM adclickedtrend WHERE"+ " date =? AND hour = ? AND minute = ? AND AdID = ?",new Object[]{trend.get_date(), trend.get_hour(), trend.get_minute(),trend.getAdID()}, new ExecuteCallBack() {public void resultCallBack(ResultSet result) throws Exception {// TODO Auto-generated method stubif(result.next()) {long count = result.getLong(1);adTrendhistory.setClickedCountHistoryLong(count);updating.add(trend);} else { inserting.add(trend);} }});}//表的字段date、hour、minute、adID、clickedCountList<Object[]> insertParametersList = new ArrayList<Object[]>();for(AdTrendStat insertRecord : inserting) {insertParametersList.add(new Object[] {insertRecord.get_date(),insertRecord.get_hour(),insertRecord.get_minute(),insertRecord.getAdID(),insertRecord.getClickedCount()});}jdbcWrapper.doBatch("INSERT INTO adclickedtrend VALUES(?, ?, ?, ?, ?)", insertParametersList);//表的字段date、hour、minute、adID、clickedCountList<Object[]> updateParametersList = new ArrayList<Object[]>();for(AdTrendStat updateRecord : updating) {updateParametersList.add(new Object[] {updateRecord.getClickedCount(),updateRecord.get_date(),updateRecord.get_hour(),updateRecord.get_minute(),updateRecord.getAdID()});}jdbcWrapper.doBatch("UPDATE adclickedtrend SET clickedCount = ? WHERE"+ " date =? AND hour = ? AND minute = ? AND AdID = ?", updateParametersList);} });return null;} });;/ Spark Streaming 执行引擎也就是Driver开始运行,Driver启动的时候是位于一条新的线程中的,当然其内部有消息循环体,用于 接收应用程序本身或者Executor中的消息,/javassc.start();javassc.awaitTermination();javassc.close();}private static JavaStreamingContext createContext(String checkpointDirectory, SparkConf conf) {// If you do not see this printed, that means the StreamingContext has been loaded// from the new checkpointSystem.out.println("Creating new context");// Create the context with a 5 second batch sizeJavaStreamingContext ssc = new JavaStreamingContext(conf, Durations.seconds(10));ssc.checkpoint(checkpointDirectory);return ssc;} }class JDBCWrapper {private static JDBCWrapper jdbcInstance = null;private static LinkedBlockingQueue<Connection> dbConnectionPool = new LinkedBlockingQueue<Connection>();static {try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} }public static JDBCWrapper getJDBCInstance() {if(jdbcInstance == null) {synchronized (JDBCWrapper.class) {if(jdbcInstance == null) {jdbcInstance = new JDBCWrapper();} }}return jdbcInstance; }private JDBCWrapper() {for(int i = 0; i < 10; i++){try {Connection conn = DriverManager.getConnection("jdbc:mysql://Master:3306/sparkstreaming","root", "root");dbConnectionPool.put(conn);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} } }public synchronized Connection getConnection() {while(0 == dbConnectionPool.size()){try {Thread.sleep(20);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} }return dbConnectionPool.poll();}public int[] doBatch(String sqlText, List<Object[]> paramsList){Connection conn = getConnection();PreparedStatement preparedStatement = null;int[] result = null;try {conn.setAutoCommit(false);preparedStatement = conn.prepareStatement(sqlText);for(Object[] parameters: paramsList) {for(int i = 0; i < parameters.length; i++){preparedStatement.setObject(i + 1, parameters[i]);} preparedStatement.addBatch();}result = preparedStatement.executeBatch();conn.commit();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if(preparedStatement != null) {try {preparedStatement.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} }if(conn != null) {try {dbConnectionPool.put(conn);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} }}return result; }public void doQuery(String sqlText, Object[] paramsList, ExecuteCallBack callback){Connection conn = getConnection();PreparedStatement preparedStatement = null;ResultSet result = null;try {preparedStatement = conn.prepareStatement(sqlText);for(int i = 0; i < paramsList.length; i++){preparedStatement.setObject(i + 1, paramsList[i]);} result = preparedStatement.executeQuery();try {callback.resultCallBack(result);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} } catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if(preparedStatement != null) {try {preparedStatement.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} }if(conn != null) {try {dbConnectionPool.put(conn);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} }} }}interface ExecuteCallBack {void resultCallBack(ResultSet result) throws Exception;}class UserAdClicked {private String timestamp;private String ip;private String userID;private String adID;private String province;private String city;private Long clickedCount;public String getTimestamp() {return timestamp;}public void setTimestamp(String timestamp) {this.timestamp = timestamp;}public String getIp() {return ip;}public void setIp(String ip) {this.ip = ip;}public String getUserID() {return userID;}public void setUserID(String userID) {this.userID = userID;}public String getAdID() {return adID;}public void setAdID(String adID) {this.adID = adID;}public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public Long getClickedCount() {return clickedCount;}public void setClickedCount(Long clickedCount) {this.clickedCount = clickedCount;} }class AdClicked {private String timestamp;private String adID;private String province;private String city;private Long clickedCount;public String getTimestamp() {return timestamp;}public void setTimestamp(String timestamp) {this.timestamp = timestamp;}public String getAdID() {return adID;}public void setAdID(String adID) {this.adID = adID;}public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public Long getClickedCount() {return clickedCount;}public void setClickedCount(Long clickedCount) {this.clickedCount = clickedCount;} }class AdProvinceTopN {private String timestamp;private String adID;private String province;private Long clickedCount;public String getTimestamp() {return timestamp;}public void setTimestamp(String timestamp) {this.timestamp = timestamp;}public String getAdID() {return adID;}public void setAdID(String adID) {this.adID = adID;}public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public Long getClickedCount() {return clickedCount;}public void setClickedCount(Long clickedCount) {this.clickedCount = clickedCount;} }class AdTrendStat {private String _date;private String _hour;private String _minute;private String adID;private Long clickedCount;public String get_date() {return _date;}public void set_date(String _date) {this._date = _date;}public String get_hour() {return _hour;}public void set_hour(String _hour) {this._hour = _hour;}public String get_minute() {return _minute;}public void set_minute(String _minute) {this._minute = _minute;}public String getAdID() {return adID;}public void setAdID(String adID) {this.adID = adID;}public Long getClickedCount() {return clickedCount;}public void setClickedCount(Long clickedCount) {this.clickedCount = clickedCount;} }class AdTrendCountHistory{private Long clickedCountHistoryLong;public Long getClickedCountHistoryLong() {return clickedCountHistoryLong;}public void setClickedCountHistoryLong(Long clickedCountHistoryLong) {this.clickedCountHistoryLong = clickedCountHistoryLong;} } 本篇文章为转载内容。原文链接:https://blog.csdn.net/tom_8899_li/article/details/71194434。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-02-14 19:16:35
298
转载
Java
...与最新进展》 随着云计算和大数据时代的到来,Java作为企业级应用开发的首选语言,其多线程技术的重要性日益凸显。近日,Oracle发布了Java 17版本,其中对并发编程的支持有了显著提升。新版本引入了Actor模型的改进版——JSR 4204,使得Java开发者能够更轻松地构建无状态、无并发问题的分布式系统。 此外,Java 17引入了JEP 395,即“Coroutines for the Java Virtual Machine”,这允许程序员在单线程环境中编写异步代码,提高了代码的简洁性和可读性。Coroutine技术结合了轻量级线程和协程的优点,使得Java程序员能更好地处理高并发场景下的任务切换。 对于线程池管理,Java 17也提供了新的优化,如对线程池大小动态调整的支持,有助于在保证系统性能的同时避免资源浪费。而Java社区对于并行计算和GPU加速的探索也在不断深入,例如Project Loom计划中的ZGC垃圾收集器,旨在提供更好的线程安全性与性能。 同时,随着微服务架构的流行,Java并发编程的挑战也转向了如何设计和管理复杂的分布式系统。研究者们正在探索如何在分布式环境中实现高效的线程通信,如零拷贝、低延迟网络编程等。 总的来说,Java多线程技术的发展不仅体现在语言层面的更新,更在于如何帮助开发者解决实际问题,提高系统的并发性能和可扩展性。无论是企业级应用开发还是新兴技术领域,Java的并发编程能力都将发挥关键作用。
2024-04-10 16:02:45
376
码农
JSON
...PI接口设计、前后端数据交互、实时通信等多个核心环节。近期,随着前端框架Vue3和React hooks等现代技术的发展,JSON数组的动态处理与渲染效率得到了显著提升。例如,开发者可以通过Vue3的reactive特性或React Hooks中的useState和useEffect对JSON数组进行高效的状态管理,并实时反映在用户界面上。 同时,随着大数据和云计算技术的普及,JSON数组在处理大规模、非结构化数据时的作用也日益凸显。如Apache Spark等分布式计算框架已支持原生JSON数据类型,使得JSON数组能在海量数据场景下实现快速解析与处理。 此外,在安全性和隐私保护方面,业界正针对JSON数组的数据传输安全推出一系列新标准和解决方案。例如,通过JSON Web Tokens(JWT)进行身份验证时,如何安全地封装和解码包含敏感信息的JSON数组成为了研究热点。 综上所述,JSON数组在现代Web开发中不仅扮演着数据交换的关键角色,而且随着技术发展不断拓展其应用场景。从提高性能优化到强化数据安全性,JSON数组的相关实践和研究都在与时俱进,为构建高效、安全的Web应用提供有力支撑。
2023-07-12 17:59:29
489
键盘勇士
Docker
...步探索其在现代云原生环境中的实际应用和最新发展动态。近日,Docker发布了最新的版本更新,强化了与Kubernetes的集成能力,使得Docker容器中的文件管理、数据持久化以及多容器间的共享存储更为便捷和安全。 同时,随着微服务架构的广泛应用,Docker Compose工具因其对多容器应用程序定义和部署的简化而备受瞩目。通过Compose文件,开发人员可以轻松配置多个容器间的数据卷挂载策略,从而确保服务间数据的可靠传输与同步。 另外,对于数据敏感型应用,诸如数据库容器等,Docker持续优化其对存储驱动的支持,如支持本地存储、网络存储(NFS、iSCSI)以及云服务商提供的块存储服务,这无疑提升了容器环境中数据的安全性和可用性。 此外,业界也在积极研究和发展基于Docker的新型文件系统解决方案,例如结合分布式存储系统以满足大规模集群环境下容器对高性能、高可用文件读写的诉求。这些前沿技术和实践为Docker在企业级应用场景中提供了更强大的支撑,也体现了容器技术在持续演进中不断解决实际问题的决心与创新力。 总之,深入掌握Docker容器中的文件读写机制,并关注其在云原生领域的发展动态和技术革新,将有助于我们在构建现代化、可扩展的应用架构时,更好地利用Docker的优势,提升开发运维效率,保障业务系统的稳定运行。
2023-12-30 15:13:37
472
编程狂人
VUE
...P实现加密通信以保障数据安全性的基础上,进一步探讨网络安全和数据加密的最新趋势和技术动态至关重要。近日,随着欧盟《通用数据保护条例》(GDPR)等法规对数据隐私保护要求的提升,全球范围内的企业和开发者都在寻求更为安全、高效的数据加密方案。 一项最新的研究指出,越来越多的企业正在采用端到端加密技术来保护其用户数据。例如,在Web应用中,除了前后端之间使用AES等算法加密传输数据外,还可以结合HTTPS协议提供传输层安全,并探索如JWT(JSON Web Tokens)等认证机制以增强整体安全性。 此外,针对密钥管理问题,区块链技术也被引入用于改进和强化密钥的安全存储和分发。一些企业开始尝试利用智能合约自动执行密钥生命周期管理,确保即使在分布式系统中也能实现安全的密钥交换。 同时,密码学领域的前沿进展也值得关注。比如,量子计算的发展对传统加密算法构成威胁,为此NIST正在进行后量子密码标准(PQC)的遴选工作,旨在找到能在量子计算机面前保持安全的新型加密算法。 综上所述,理解并熟练运用Vue与PHP进行加密通信只是构建安全Web应用的第一步,持续关注和学习最新的加密技术和行业规范,才能更好地应对不断变化的网络环境,确保敏感信息在网络空间中的安全流转。
2023-12-15 17:02:45
141
编程狂人
Docker
...可以构建、发布和运行分布式应用。在本文语境下,Docker作为一种容器化技术,允许用户创建和管理隔离的环境(即容器),确保程序在不同环境下运行的一致性,但可能带来时钟同步问题。 容器化技术 , 容器化技术是现代软件开发和部署的一种重要手段,它将应用程序以及其运行所需的所有依赖资源(如库、配置文件等)封装在一个独立、轻量级的可执行包中,这个包被称为“容器”。在文中,Docker是实现容器化的重要工具,通过容器化技术,可以在不同的主机系统上保持一致的应用程序运行环境,但时钟同步是需要解决的一个关键问题。 NTP服务 , 网络时间协议(Network Time Protocol, NTP)是一项用于在计算机网络中同步所有设备系统时钟的服务。在本文中,NTP服务被用于解决Docker容器内时钟与外部世界不一致的问题。通过在容器内部安装并配置NTP服务,容器可以从指定的NTP服务器(如pool.ntp.org)获取准确的时间信息,并自动调整自身系统时钟,从而确保容器内应用程序能够获得精确的时间数据。
2023-10-26 12:53:07
468
程序媛
MySQL
...接后,进一步深入探讨数据库安全与远程访问优化至关重要。近日,随着云计算和分布式应用的普及,MySQL数据库远程管理的需求日益增加,但同时也带来了更严峻的安全挑战。据2022年的一份网络安全报告指出,针对数据库系统的未授权访问攻击事件增长了近30%,其中大量案例源于弱口令或不当的远程访问设置。 为强化MySQL远程连接安全性,建议关注以下几个方面: 1. 强化身份验证机制:采用双因素认证或多因素认证,避免仅依赖用户名和密码;启用MySQL的SSL加密连接功能,确保数据传输过程中的安全性。 2. 权限最小化原则:遵循“按需分配”的权限策略,只给每个用户提供完成其工作所需的最低权限,减少潜在的安全风险。 3. 定期审计与更新:定期审查MySQL用户表中的远程访问权限设置,及时移除不再需要的远程访问账号;同时保持MySQL服务器及其插件的版本更新,利用最新安全补丁修复已知漏洞。 4. 配合防火墙规则:在服务器层面,结合IPtables或其他防火墙工具精细控制对MySQL服务端口(默认3306)的访问,只允许特定可信IP地址进行远程连接。 5. 利用专门的数据库访问代理服务:对于大型企业或高安全需求场景,可考虑部署数据库访问代理服务,如Amazon RDS Proxy、Azure Database for MySQL Flexible Server等,它们提供了细粒度的访问控制、负载均衡及日志审计等功能,有助于提升远程访问MySQL数据库的整体安全性。 总之,在实现MySQL数据库远程访问便利性的同时,务必重视并实施严格的安全措施,以确保数据库资源不被恶意利用,有效保障企业信息资产的安全。
2023-12-17 16:15:36
63
数据库专家
JSON
...SON是一种轻量级的数据交换格式,它基于JavaScript的一个子集,易于人阅读和编写,同时也易于机器解析和生成。JSON数据由键值对构成,其值可以是字符串、数字、布尔值、数组、null以及其它嵌套的JSON对象。在Web开发领域,JSON广泛应用于前后端之间的数据传输,因为它具有良好的跨语言兼容性,便于不同系统之间进行数据交换。 WebAssembly , WebAssembly是一种低级的类汇编语言,设计初衷是为了在现代网络浏览器中实现接近本机代码性能的高性能应用。WebAssembly模块可以在多种编程语言(如C/C++、Rust等)中编写并编译成字节码形式,然后在浏览器环境中运行。尽管文章中未直接提及WebAssembly,但在处理高精度计算或需要优化性能的场景下,它可以作为一种解决方案,通过在JavaScript环境中执行WebAssembly模块以达到更精确的浮点数运算效果,进而解决JSON中数值精度问题。
2023-03-17 15:37:33
315
程序媛
JSON
...on,是一种轻量级的数据交换格式。它基于文本,易于阅读和编写,并且可以被机器解析和生成。在文中,JSON用于表示一系列数据对象(如水果的属性),其结构清晰、紧凑,采用键值对的形式存储信息,广泛应用于前后端数据交互、配置文件存储、API接口设计等多个领域。 RESTful API , Representational State Transfer(表述性状态转移)风格的Web服务应用程序编程接口。RESTful API遵循HTTP协议规范,通过定义一套资源标识符以及与之对应的HTTP方法(GET、POST、PUT、DELETE等),实现对资源的操作和管理。在文章语境中,JSON作为主流的数据交换格式,在RESTful API设计中扮演重要角色,使得数据传输简洁高效,接口易用性增强。 NoSQL数据库 , Not Only SQL,泛指非关系型数据库,相较于传统的关系型数据库,NoSQL数据库更适合处理大规模分布式环境下的海量数据存储与查询问题。文中提到MongoDB就是一种NoSQL数据库,它可以原生支持JSON格式数据的存储和查询,利用JSON文档模型的优势,简化了数据操作流程,提高了开发效率。
2023-01-19 19:48:00
520
代码侠
Docker
...入了解了Docker数据恢复的方法后,我们进一步探讨如何在实际生产环境中有效实施和优化这些策略。近期,随着容器化技术的广泛应用,Docker数据保护的重要性日益凸显。2022年,一家知名云服务提供商发布了一份关于“容器数据保护最佳实践”的报告,其中详细阐述了定期备份、异地存储以及自动化数据恢复流程等关键环节,并强调了采用一致性快照以确保数据完整性。 同时,开源社区也在持续推动相关工具的发展,例如Portworx的Stork项目提供了对Kubernetes和Docker数据卷的一键式备份与恢复支持,大大简化了操作流程。此外,通过深度集成如Velero(原名为Heptio Ark)这类开源灾备工具,企业能够实现跨集群的数据迁移和灾难恢复,增强了基于Docker的应用系统的韧性。 另外,对于更复杂的企业级场景,有专家建议结合使用分布式文件系统(如Ceph或GlusterFS)来持久化和备份Docker数据卷,从而提高数据安全性及可用性。实践中,不断优化数据恢复方案,使之与业务连续性和高可用性要求相匹配,是每一个依赖于Docker运行关键业务的企业必须面对的挑战。 总而言之,在数字化转型加速的今天,理解并掌握先进的Docker数据备份与恢复策略已成为IT运维人员必备技能之一。只有紧跟技术发展潮流,结合实际情况灵活运用各种解决方案,才能确保即使在遭遇意外情况时,也能迅速有效地恢复业务运行,最大限度地降低数据丢失带来的潜在风险和损失。
2023-04-14 09:42:03
301
码农
MySQL
关系型数据库管理系统(RDBMS) , 关系型数据库管理系统是一种基于关系模型的数据库管理系统,它以表格的形式存储数据,并通过预定义的关系来组织和管理这些表格中的数据。在MySQL中,RDBMS允许用户通过SQL语言对数据进行查询、更新、删除等操作,并确保数据的一致性和完整性。在文章语境中,MySQL作为最广泛使用的关系型数据库管理系统,具备高性能和可扩展性等优点。 分布式系统 , 分布式系统是由多台计算机通过网络连接并协同工作,共同完成一个或多个任务的计算系统。在MySQL的分布式实现中,多台计算机组成集群,每台计算机处理部分数据库负载,它们之间相互协作,实现数据共享和高可用性,以此提高整个系统的处理能力和并发性能。 MySQL Proxy , MySQL Proxy是一款轻量级的中间件软件,设计用于MySQL数据库的负载均衡、读写分离以及访问控制等功能。在MySQL分布式架构中,MySQL Proxy接收客户端的所有数据库请求,根据预设策略将这些请求分发到不同的MySQL服务器上,从而实现数据库访问流量的均衡分布,保证系统整体性能和高可用性。此外,MySQL Proxy还支持复制和故障转移功能,增强了MySQL分布式环境下的稳定性和可靠性。
2023-02-25 16:35:15
123
逻辑鬼才
DorisDB
...orisDB如何处理数据文件重复与冲突问题后,进一步关注数据库领域对于数据一致性和冗余问题的最新研究动态和解决方案显得尤为重要。近日,Apache Cassandra社区发布了一项针对分布式环境下数据冲突解决策略的重大更新,引入了更为智能且实时的多版本并发控制(MVCC)机制,有效提升了大规模分布式数据库系统中数据一致性保障的能力。 同时,在存储优化方面,Google发布的“Colossus”文件系统架构升级中,创新性地采用稀疏索引技术减少数据冗余,并通过全局命名空间管理和跨数据中心的数据同步,确保了数据的一致性和高可用性。这对于理解并优化DorisDB乃至其他数据库系统的数据管理方式具有重要参考价值。 此外,业界也在深入探索区块链技术在保证数据一致性和解决冲突中的应用潜力。以IBM、微软等科技巨头为例,他们正在研究利用区块链的分布式账本特性,实现对数据库操作的原子性、一致性、隔离性和持久性(ACID)属性的强化,从而为复杂环境下的数据一致性难题提供新的思路和方案。 综上所述,结合当前数据库领域的前沿技术和研究成果,将有助于我们更全面地审视和应对数据文件重复或冲突的问题,不断提升DorisDB及类似数据库产品的性能表现与稳定性,满足日益增长的大数据处理需求。
2023-03-25 12:27:57
561
雪落无痕-t
JSON
...其在现代Web开发和数据处理中的实际应用。近日,随着API经济的快速发展,高效精准地处理API返回的大量JSON数据成为了众多开发者关注的焦点。例如,前端工程师在对接后端接口时,经常需要根据页面需求筛选并显示部分JSON数据,此时JSON属性过滤器就显得尤为重要。 据TechCrunch报道,许多现代JavaScript框架如React、Vue.js等已内建或推荐使用专门的数据处理库(如Lodash、Ramda等),它们提供了丰富的函数以简化JSON属性过滤操作,极大地提升了开发效率和代码可读性。这些库不仅支持基础的属性提取,还能进行深度查找和复杂条件下的过滤。 同时,在大数据和云计算领域,像Apache Spark等分布式计算框架也支持对JSON数据进行高效的属性过滤与转换,以便于后续分析与存储。通过运用特定的过滤策略,企业能够快速从海量JSON日志或其他半结构化数据中提炼关键信息,辅助业务决策。 此外,对于那些注重隐私保护和数据最小化原则的应用场景,JSON属性过滤技术同样发挥着不可或缺的作用。在GDPR等相关法规的要求下,开发者必须确保只收集和传输必要的用户数据,这时精细到属性级别的过滤功能就能有效防止数据泄露风险。 总之,JSON属性过滤器及其相关技术不仅是提升开发效率的重要手段,也是应对当前大数据时代挑战,实现数据安全、合规使用的必备工具。无论是前端交互逻辑优化,还是后端大规模数据处理,乃至云端数据合规流通,深入理解和掌握JSON属性过滤方法都将带来显著的价值提升。
2023-02-21 22:09:00
546
电脑达人
MySQL
...况后,进一步深入探讨数据库性能优化和内存管理的重要性显得尤为关键。近期,随着数据量的爆炸性增长,许多企业级应用开始面临数据库响应速度下降的问题,其中内存管理和有效利用虚拟内存成为解决这一问题的核心策略之一。 2022年,Oracle官方发布的MySQL 8.0版本中,对内存管理机制进行了大幅优化升级,引入了一系列新特性,如改进的查询缓存策略、更精细的内存分配控制以及智能内存压缩技术等,使得MySQL能够更高效地在物理内存与虚拟内存之间进行切换,极大提升了大容量数据处理时的性能表现。 同时,业界专家建议,在系统层面合理配置交换空间大小以支持MySQL虚拟内存需求,并结合监控工具实时分析MySQL及其所在服务器的内存使用状况,以便及时发现并调整潜在的内存瓶颈。例如,通过定期审查query_cache_size等关键参数,根据实际业务负载动态调整其值,避免无谓的内存浪费或过度依赖虚拟内存导致性能下滑。 此外,对于大型分布式数据库系统而言,采用内存计算、混合存储架构以及先进的内存池技术也是提升数据库整体性能的有效手段。比如,阿里云自主研发的PolarDB-X数据库产品,就借助了智能内存管理和分布式缓存技术,实现了对大规模数据访问场景下虚拟内存使用的深度优化,从而确保了服务端的稳定高效运行。 综上所述,掌握MySQL虚拟内存查看方法仅仅是性能调优的第一步,了解并运用最新的内存管理技术、紧跟数据库发展趋势,才能更好地应对大数据时代带来的挑战,确保数据库系统的高性能、高可用与可扩展性。
2023-03-15 10:31:00
95
程序媛
转载文章
...起,P2P领域的生态环境已发生了显著变化。 近期,一些P2P技术正被应用于区块链领域以实现去中心化存储与传输。例如IPFS(InterPlanetary File System)协议利用了P2P网络的概念,旨在创建一个分布式web,提高数据存储的安全性和效率。与此同时,像BitTorrent这样的老牌公司也在积极研发新的应用模式,比如BitTorrent Speed,通过激励机制鼓励用户共享带宽资源,从而提升整体下载速度。 另外值得注意的是,各国对P2P技术合法合规使用的监管态度亦在不断调整。在美国,最高法院针对Groshar和Morpheus等P2P软件涉及版权侵权的案件判决,对行业产生了深远影响;而在欧洲,欧盟法院最近的一些裁决则试图在保护版权和技术创新之间寻求平衡。 此外,对于个人隐私保护和网络安全问题,新型P2P软件也做出了相应改进,如某些私有种子(Private Tracker)社区和加密型P2P工具,它们限制非法传播并强化用户隐私保护,力求在合法合规的前提下延续P2P技术的生命力。 总之,虽然传统的P2P文件分享软件列表可能已经发生变化,但P2P技术本身仍在持续演进,不仅在数字内容分发方面继续发挥作用,还在区块链、云计算等领域寻找新的应用场景,并在全球范围内面临来自法律和伦理的双重挑战与机遇。
2023-02-03 12:58:00
116
转载
Apache Pig
在大数据处理领域,Apache Pig作为Hadoop生态系统中的重要组件,其对数据类型的全面支持极大地提升了大规模数据分析的效率。随着近年来数据量爆炸性增长和实时计算需求的提升,Pig也在不断进化以适应新的挑战。例如,Apache社区正积极推动Pig与Spark、Flink等现代大数据处理框架的集成,使得用户可以在Pig脚本中利用这些框架的高性能特性。 此外,Pig还引入了对更复杂数据类型如Avro、Parquet等的支持,这些列式存储格式大大优化了读写性能并节省存储空间。通过结合Pig的数据类型体系与这些先进的数据格式,数据工程师可以构建更为高效且易于维护的数据管道。 近期,有研究者进一步探索了如何在Pig中实现深度学习模型的应用,将原本需要在Python或Scala环境中运行的机器学习任务,通过Pig UDF(用户自定义函数)的形式进行封装,从而实现在大数据平台上无缝执行深度学习推理任务。这一发展趋势充分体现了Pig作为数据预处理工具的强大扩展性和生命力,也揭示了未来大数据处理技术向着跨平台整合、多元化数据类型支持及智能化应用方向迈进的趋势。
2023-01-14 19:17:59
481
诗和远方-t
ActiveMQ
...其订阅机制以适应现代分布式系统的要求。 例如,Apache Kafka利用其分区和副本机制确保了消息的持久化和高可用性,即使Broker重启或故障,消费者也能通过跟踪偏移量恢复消费状态。而RabbitMQ则提供了镜像队列功能,使得即使节点失效,订阅者仍可以从其它包含相同数据的队列中继续获取消息。 同时,在ActiveMQ社区,开发者们也正在积极探讨如何进一步改进非持久订阅的可靠性。比如,通过引入新的配置选项或者结合外部存储方案,可能在未来版本中提供更为灵活且兼顾实时性和可靠性的订阅模式。 此外,深入理解CAP理论(一致性、可用性和分区容错性)对于设计和选择合适的消息中间件至关重要。在实际应用场景中,我们需根据业务需求权衡并确定是优先保证消息的实时传递还是数据的完整性,从而更好地指导我们在ActiveMQ或其他消息队列产品中的技术选型与实现策略。
2023-03-05 16:49:49
351
青春印记-t
Kibana
...ana 是一个开源的数据可视化平台,主要用于对Elasticsearch中的数据进行实时分析和可视化展示。在文中,用户在使用Kibana进行数据可视化操作时遇到了无法访问内部API的问题。 Elasticsearch服务 , Elasticsearch是一个基于Lucene的分布式、RESTful搜索引擎,能够处理大规模数据的近实时搜索与分析。在本文上下文中,Elasticsearch服务作为Kibana的数据后端,为Kibana提供数据检索和API接口,当其出现异常或未启动时,可能导致Kibana无法正常访问内部API。 API(Application Programming Interface) , API是一种让软件之间交互和通信的标准方式,它定义了软件组件如何互相调用并交换信息。在本文中,Kibana内部API指的是Kibana系统内部用于获取、处理和展示Elasticsearch中数据的一系列接口。如果这些API调用失败,将直接影响到Kibana的数据展现和分析功能。 配置文件(kibana.yml) , 在Kibana中,kibana.yml是一个核心配置文件,用于存储和管理Kibana的各种设置参数,如Elasticsearch服务地址、网络配置、安全性设置等。当此文件中的配置错误,特别是与API访问权限或URL路径相关的设置有误时,可能会导致Kibana无法正确调用内部API。 Role-Based Access Control (RBAC) , 角色基于访问控制,是一种常见的授权机制,用于根据用户的角色分配不同级别的系统资源访问权限。在Elasticsearch中,通过实现RBAC可以精细控制不同用户对Elasticsearch API的访问权限,防止因权限设置不当引发的API调用失败问题。
2023-10-18 12:29:17
610
诗和远方-t
ActiveMQ
...一种软件或服务,它在分布式系统中充当通信代理,允许不同的应用程序组件之间进行异步解耦的消息传递。在本文的上下文中,ActiveMQ就是一种开源的消息中间件产品,它提供了可靠的消息传输、队列管理以及消息选择器等功能,使得分布式系统中的不同模块可以高效、灵活地交换信息。 消息选择器 , 消息选择器是消息中间件提供的一种功能,用于在接收和处理消息时根据预定义的条件对消息进行筛选。在使用ActiveMQ时,开发者可以通过设置消息选择器来决定哪些消息将被消费者接收和处理,从而实现精细化的消息过滤。例如,可以根据消息携带的属性值(如color= red )仅接收符合特定条件的消息。 分布式系统 , 分布式系统是由多台计算机通过网络互相连接并协同工作而形成的系统。在这个系统中,各个节点相互独立且能并发执行任务,共同完成复杂的计算或数据处理任务。在讨论ActiveMQ及其消息选择器功能时,分布式系统是其应用场景的基础背景,因为消息中间件在解决分布式系统中各组件间通信问题时发挥着关键作用,能够确保系统的可靠性和扩展性。
2023-03-11 13:19:06
929
山涧溪流-t
RocketMQ
...款高性能产品,在解决分布式系统中消息积压问题上展现出了强大的实力。近期,随着云计算和大数据技术的快速发展,以及微服务架构在企业级应用中的普及,消息队列在保证系统解耦、提升并发处理能力和数据一致性等方面的作用愈发凸显。 2021年,Apache RocketMQ社区持续推动项目迭代升级,发布了RocketMQ 5.0版本,不仅优化了原有的消息堆积处理机制,还引入了全新的智能调度策略和流量控制算法,有效应对大规模消息洪峰场景下的积压问题。同时,该版本强化了对Kubernetes等云原生环境的支持,实现了弹性扩缩容和资源利用率的大幅提升。 此外,针对消息积压可能导致的数据丢失风险,业界也在积极探讨和实践基于事件驱动架构(EDA)的新解决方案,通过将消息中间件与流处理、实时计算等技术相结合,实现对积压消息的实时分析与快速响应,从而进一步保障系统的稳定性和可靠性。 总的来说,无论是从RocketMQ等主流消息中间件的功能演进,还是从新兴技术在处理消息积压问题上的创新应用,都表明了我们正在不断深化对分布式系统可靠性和稳定性的理解与实践,以适应日益复杂严苛的业务需求和技术挑战。
2023-03-14 15:04:18
160
春暖花开-t
ElasticSearch
...文中,URL模板帮助数据分析师在ElasticSearch中根据需要迅速定位并获取指定范围、类型或其他特定条件下的数据。 钻取(Drilldown)操作 , 在数据分析领域,钻取是指从概括性的高层面数据逐步深入到详细数据的过程。它允许用户从汇总数据开始,然后逐层向下探索更具体的数据细节。在Kibana中,通过设置和使用URL模板实现钻取操作,用户能够快速锁定并挖掘海量数据中的目标信息,提高分析效率。 ElasticSearch , Elasticsearch是一个基于Lucene构建的开源分布式全文搜索引擎,专为云计算环境设计,提供近实时搜索、分析以及存储数据的能力。在本文中,ElasticSearch是承载大数据分析的基础平台,与Kibana可视化工具结合使用,使得用户能够利用URL模板等高级功能高效地进行数据搜索和分析工作。
2023-08-09 23:59:55
495
雪域高原-t
JQuery
...入理解了jQuery中数据数值型转化的方法后,我们可以进一步探索JavaScript和Web开发领域中关于数据类型处理的最新趋势和技术动态。例如,随着ECMAScript(ES)规范的不断演进,最新的ES2021引入了BigInt类型以支持任意大小的整数计算,这对于处理大数据量或精确数学运算具有重要意义。另外,对于可能包含非标准格式数字的字符串转换问题,开发者可以关注Intl.NumberFormat API,它提供了强大的本地化数字格式化能力,能有效解决国际化场景下的数字转换需求。 同时,在前端性能优化方面,合理而准确的数据类型转化能够显著提升代码执行效率,减少潜在的运行时错误。比如,通过TypeScript等静态类型检查工具提前发现并修正类型转换问题,已经成为现代前端工程化实践中的重要环节。近期,一项关于浏览器内部机制的研究指出,对DOM操作中的数据类型进行预处理和优化,可有效提升页面渲染速度和用户体验。 此外,针对实际项目开发中可能遇到的具体问题,诸如如何在JSON.parse过程中更灵活地处理数值类型,或者如何利用lodash、Ramda等函数式编程库进行更为精细的数据类型转化,都是值得开发者深入了解和探讨的话题。总的来说,随着技术的发展与进步,理解和掌握高效、精准的数据类型转化策略,将在不断提升应用性能的同时,也有助于保障代码的质量和稳定性。
2023-09-13 16:02:10
149
编程狂人
站内搜索
用于搜索本网站内部文章,支持栏目切换。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
du -sh *
- 显示当前目录下各文件及子目录所占用的空间大小(以人类可读格式)。
推荐内容
推荐本栏目内的其它文章,看看还有哪些文章让你感兴趣。
2023-04-28
2023-08-09
2023-06-18
2023-04-14
2023-02-18
2023-04-17
2024-01-11
2023-10-03
2023-09-09
2023-06-13
2023-08-07
2023-03-11
历史内容
快速导航到对应月份的历史文章列表。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"