topN功能是一个非常常见的功能,比如查看最近几分钟的阅读最高数,购买最高数。
flink实现topN的功能也非常方便,下面就开始构建一个flink topN的程序。
还是像上篇博客一样,从kafka读取数据,然后进行计算和数据转换,最后sink到mysql中。
假设有个需求,实现一个统计每5分钟最高购买数的商品。
使用maven创建一个工程,具体步骤可以参考上边博文。然后创建一个数据库表,用于存储最终的结果集。语句如下:
CREATE TABLE `itembuycount` ( `id` mediumint NOT NULL auto_increment, `itemId` bigint(255) NOT NULL, `buyCount` bigint(11) DEFAULT NULL, `createDate` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
创建一个表对应的pojo类文件UserAction。里边主要是用户id,商品id,用户的行为,pv用户浏览,buy用户购买,cart加购物车,fav加入收藏。
package myflinktopn.pojo; /** * @author huangqingshi * @Date 2019-12-13 */ public class UserAction { public long userId; //用户id public long itemId; //商品id public int categoryId; //商品分类id public String behavior; //用户行为(pv, buy, cart, fav) public long timestamp; //操作时间戳 public long getUserId() { return userId; } public void setUserId(long userId) { this.userId = userId; } public long getItemId() { return itemId; } public void setItemId(long itemId) { this.itemId = itemId; } public int getCategoryId() { return categoryId; } public void setCategoryId(int categoryId) { this.categoryId = categoryId; } public String getBehavior() { return behavior; } public void setBehavior(String behavior) { this.behavior = behavior; } public long getTimestamp() { return timestamp; } public void setTimestamp(long timestamp) { this.timestamp = timestamp; } }
接下来创建一个kafka主题,存储发送和接受数据使用。
./bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic USER_ACTION
kafka的主题创建好了之后,写一个程序往kafka里边写数据,一秒写一条。
package myflinktopn.kafka; import com.alibaba.fastjson.JSON; import myflinktopn.pojo.UserAction; import org.apache.commons.lang3.RandomUtils; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.ProducerRecord; import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.concurrent.TimeUnit; /** * @author huangqingshi * @Date 2019-12-07 */ public class KafkaWriter { //本地的kafka机器列表 public static final String BROKER_LIST = "localhost:9092"; //kafka的topic public static final String TOPIC_USER_ACTION = "USER_ACTION"; //key序列化的方式,采用字符串的形式 public static final String KEY_SERIALIZER = "org.apache.kafka.common.serialization.StringSerializer"; //value的序列化的方式 public static final String VALUE_SERIALIZER = "org.apache.kafka.common.serialization.StringSerializer"; //用户的行为列表 public static final List<String> userBehaviors = Arrays.asList("pv", "buy", "cart", "fav"); public static void writeToKafka() throws Exception{ Properties props = new Properties(); props.put("bootstrap.servers", BROKER_LIST); props.put("key.serializer", KEY_SERIALIZER); props.put("value.serializer", VALUE_SERIALIZER); KafkaProducer<String, String> producer = new KafkaProducer<>(props); UserAction userAction = new UserAction(); userAction.setUserId(RandomUtils.nextLong(1, 100)); userAction.setItemId(RandomUtils.nextLong(1, 1000)); userAction.setCategoryId(RandomUt