快捷搜索:  汽车  科技

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)% docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 574d30f17868 mysql "docker-entrypoint.s…" 14 months ago Up 2 days 0.0.0.0:3306->3306/tcp :::3306->3306/tcp 33060/tcp mysql-test1.2 安装redis查询 redis 的镜像docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1

前言

有时候我们需要快速启动一些项目,但是环境往往折腾了好久,因此弄一个可以重用的快速搭建的教程, docker 简直就是这方面的神器,Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化。

本教程基于的前提条件:

  • 机器已经安装配置好 JDK1.8 ,并且环境变量已经配置成功
  • Maven 已经配置好, IDEA 项目使用的默认方式 Maven 也配置成功
  • 本地机器安装好 Docker
  • 顺便提一句,我用 navicat 作为数据库可视化操作工具

项目地址: https://github.com/Damaer/DemoCode/tree/main/springboot/springdemo

项目目录

├── src :源代码 | ├── main | | ├── java | | | ├── com.aphysia.springbootdemo | | | | ├── config:配置 | | | | | ├── RedisConfig:redis配置 | | | | ├── constant:常量 | | | | | ├── RedisConfig:Redis常量 | | | | ├── controller:控制器 | | | | ├── mapper:数据库操作接口 | | | | ├── model:实体类 | | | | ├── service:逻辑处理层,包括接口以及实现类 | | | | | ├── impl:接口实现类 | | | | ├──util:工具类 | | | | | ├── RedisUtil:redis工具类 | | | | ├──SpringdemoApplication:启动类 | | ├── resource | | | ├── mapper 数据库操作sql | | | ├── application.yml:全局配置类 | | | ├── user.SQL: 初始化mysql | ├── test: 测试类 ├── pom.xml :项目maven依赖关系

整体的目录如下:

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(1)

搭建项目1. docker安装启动mysql以及redis1.1 安装mysql

查询 mysql 最新的镜像:

docker search mysql

拉取最新的 mysql 版本

docker pull mysql:latest

启动 mysql ,用户名 root 密码 123456

docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql

可以通过 docker ps 查看是否安装成功

% docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 574d30f17868 mysql "docker-entrypoint.s…" 14 months ago Up 2 days 0.0.0.0:3306->3306/tcp :::3306->3306/tcp 33060/tcp mysql-test

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(2)

1.2 安装redis

查询 redis 的镜像

docker search redis

拉取 redis 的最新镜像

% docker pull redis:latest latest: Pulling from library/redis eff15d958d66: Pull complete 1aca8391092b: Pull complete 06e460b3ba1b: Pull complete def49df025c0: Pull complete 646c72a19e83: Pull complete db2c789841df: Pull complete Digest: sha256:619af14d3a95c30759a1978da1b2ce375504f1af70ff9eea2a8e35febc45d747 Status: Downloaded newer image for redis:latest docker.io/library/redis:latest

docker images 可以查看我们安装了哪些镜像 可以看到其实我之前也安装过 redis 的镜像:

% docker images REPOSITORY TAG IMAGE ID CREATED SIZE redis latest 40c68ed3a4d2 3 days ago 113MB redis <none> 84c5f6e03bf0 14 months ago 104MB mysql latest e1d7dc9731da 14 months ago 544MB docker/getting-started latest 1f32459ef038 16 months ago 26.8MB

让我们启动一下 redis 的容器:

% docker run -itd --name redis-test -p 6379:6379 redis 7267e14faf93a0e416c39eeaaf51705dc4b6dc3507a68733c20a2609ade6dcd6

可以看到 docker 里面现在有 redis 和 mysql 两个容器在跑了:

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(3)

2. 初始化数据库

主要是创建数据库以及测试使用的数据表,初始化数据库的语句:

drop database IF EXISTS test; CREATE DATABASE test; use test; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL `name` varchar(255) DEFAULT "" `age` int(11) DEFAULT 0 PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `user` VALUES (1 '李四' 11); INSERT INTO `user` VALUES (2 '王五' 11);

初始化数据如下:

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(4)

3.创建项目

在IDEA中,File --> New --> Project --> Spring Initializr(选择JDK 8):

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(5)

点击 Next :

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(6)

选择 Web 下面的 Spring Web , SQL 下面的 jdbc API Mybatis , NoSQL 下的 Redis 也可以不选,直接在 pom 文件里自己加入即可:

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(7)

一路点 Next 最后 Finish 创建好之后,记得更新一下 Maven ,安装依赖包。

4.初始化代码4.1 全局配置文件以及启动类

全局配置文件 application.yml :

server: port: 8081 spring: #数据库连接配置 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8&useSSL=false username: root password: 123456 redis: host: 127.0.0.1 ## redis所在的服务器IP port: 6379 ##密码,我这里没有设置,所以不填 password: ## 设置最大连接数,0为无限 pool: max-active: 8 min-idle: 0 max-idle: 8 max-wait: -1 #mybatis的相关配置 mybatis: #mapper配置文件 mapper-locations: classpath:mapper/*.xml type-aliases-package: com.aphysia.spingbootdemo.model #开启驼峰命名 configuration: map-underscore-to-camel-case: true logging: level: root: debug

启动类 SpringdemoApplication :

import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.aphysia.springdemo.mapper") public class SpringdemoApplication { public static void main(String[] args) { SpringApplication.run(SpringdemoApplication.class args); } }4.2 实体类

与数据库中user表对应的实体类 User.java :

package com.aphysia.springdemo.model; public class User { int id; String name; int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }4.3 Redis工具类

Redis 配置类 RedisConfig :

package com.aphysia.springdemo.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Autowired private RedisTemplate redisTemplate; @Bean public RedisTemplate redisTemplateInit() { //设置序列化Key的实例化对象 redisTemplate.setKeySerializer(new StringRedisSerializer()); //设置序列化Value的实例化对象 redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } }

Redis 常量类 RedisConstant :

package com.aphysia.springdemo.constant; public class RedisConstant { public static String ALL_USER_KEY = "allUser"; }

Redis 工具类 RedisUtil :

package com.aphysia.springdemo.util; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; @Component public class RedisUtil { @Resource private RedisTemplate<String Object> redisTemplate; public void setRedisTemplate(RedisTemplate<String Object> redisTemplate) { this.redisTemplate = redisTemplate; } /** * 指定缓存失效时间 * * @param key 键 * @param time 时间(秒) */ public boolean expire(String key long time) { try { if (time > 0) { redisTemplate.expire(key time TimeUnit.SECONDS); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据key 获取过期时间 * * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */ public long getExpire(String key) { return redisTemplate.getExpire(key TimeUnit.SECONDS); } /** * 判断key是否存在 * * @param key 键 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除缓存 * * @param key 可以传一个值 或多个 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key)); } } } //============================String============================= /** * 普通缓存获取 * * @param key 键 * @return 值 */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * * @param key 键 * @param value 值 * @return true成功 false失败 */ public boolean set(String key Object value) { try { redisTemplate.opsForValue().set(key value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通缓存放入并设置时间 * * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 * @return true成功 false 失败 */ public boolean set(String key Object value long time) { try { if (time > 0) { redisTemplate.opsForValue().set(key value time TimeUnit.SECONDS); } else { set(key value); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 递增 * * @param key 键 * @param delta 要增加几(大于0) * @return */ public long incr(String key long delta) { if (delta < 0) { throw new RuntimeException("递增因子必须大于0"); } return redisTemplate.opsForValue().increment(key delta); } /** * 递减 * * @param key 键 * @param delta 要减少几(小于0) * @return */ public long decr(String key long delta) { if (delta < 0) { throw new RuntimeException("递减因子必须大于0"); } return redisTemplate.opsForValue().increment(key -delta); } //================================Map================================= /** * HashGet * * @param key 键 不能为null * @param item 项 不能为null * @return 值 */ public Object hget(String key String item) { return redisTemplate.opsForHash().get(key item); } /** * 获取hashKey对应的所有键值 * * @param key 键 * @return 对应的多个键值 */ public Map<Object Object> hmget(String key) { return redisTemplate.opsForHash().entries(key); } /** * HashSet * * @param key 键 * @param map 对应多个键值 * @return true 成功 false 失败 */ public boolean hmset(String key Map<String Object> map) { try { redisTemplate.opsForHash().putAll(key map); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * HashSet 并设置时间 * * @param key 键 * @param map 对应多个键值 * @param time 时间(秒) * @return true成功 false失败 */ public boolean hmset(String key Map<String Object> map long time) { try { redisTemplate.opsForHash().putAll(key map); if (time > 0) { expire(key time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一张hash表中放入数据 如果不存在将创建 * * @param key 键 * @param item 项 * @param value 值 * @return true 成功 false失败 */ public boolean hset(String key String item Object value) { try { redisTemplate.opsForHash().put(key item value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一张hash表中放入数据 如果不存在将创建 * * @param key 键 * @param item 项 * @param value 值 * @param time 时间(秒) 注意:如果已存在的hash表有时间 这里将会替换原有的时间 * @return true 成功 false失败 */ public boolean hset(String key String item Object value long time) { try { redisTemplate.opsForHash().put(key item value); if (time > 0) { expire(key time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除hash表中的值 * * @param key 键 不能为null * @param item 项 可以使多个 不能为null */ public void hdel(String key Object... item) { redisTemplate.opsForHash().delete(key item); } /** * 判断hash表中是否有该项的值 * * @param key 键 不能为null * @param item 项 不能为null * @return true 存在 false不存在 */ public boolean hHasKey(String key String item) { return redisTemplate.opsForHash().hasKey(key item); } /** * hash递增 如果不存在 就会创建一个 并把新增后的值返回 * * @param key 键 * @param item 项 * @param by 要增加几(大于0) * @return */ public double hincr(String key String item double by) { return redisTemplate.opsForHash().increment(key item by); } /** * hash递减 * * @param key 键 * @param item 项 * @param by 要减少记(小于0) * @return */ public double hdecr(String key String item double by) { return redisTemplate.opsForHash().increment(key item -by); } //============================set============================= /** * 根据key获取Set中的所有值 * * @param key 键 * @return */ public Set<Object> sGet(String key) { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 根据value从一个set中查询 是否存在 * * @param key 键 * @param value 值 * @return true 存在 false不存在 */ public boolean sHasKey(String key Object value) { try { return redisTemplate.opsForSet().isMember(key value); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将数据放入set缓存 * * @param key 键 * @param values 值 可以是多个 * @return 成功个数 */ public long sSet(String key Object... values) { try { return redisTemplate.opsForSet().add(key values); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 将set数据放入缓存 * * @param key 键 * @param time 时间(秒) * @param values 值 可以是多个 * @return 成功个数 */ public long sSetAndTime(String key long time Object... values) { try { Long count = redisTemplate.opsForSet().add(key values); if (time > 0) expire(key time); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 获取set缓存的长度 * * @param key 键 * @return */ public long sGetSetSize(String key) { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 移除值为value的 * * @param key 键 * @param values 值 可以是多个 * @return 移除的个数 */ public long setRemove(String key Object... values) { try { Long count = redisTemplate.opsForSet().remove(key values); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } //===============================list================================= /** * 获取list缓存的内容 * * @param key 键 * @param start 开始 * @param end 结束 0 到 -1代表所有值 * @return */ public List<Object> lGet(String key long start long end) { try { return redisTemplate.opsForList().range(key start end); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 获取list缓存的长度 * * @param key 键 * @return */ public long lGetListSize(String key) { try { return redisTemplate.opsForList().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 通过索引 获取list中的值 * * @param key 键 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 * @return */ public Object lGetIndex(String key long index) { try { return redisTemplate.opsForList().index(key index); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 * @return */ public boolean lSet(String key Object value) { try { redisTemplate.opsForList().rightPush(key value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 * @param time 时间(秒) * @return */ public boolean lSet(String key Object value long time) { try { redisTemplate.opsForList().rightPush(key value); if (time > 0) expire(key time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 * @return */ public boolean lSet(String key List<Object> value) { try { redisTemplate.opsForList().rightPushAll(key value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 * @param time 时间(秒) * @return */ public boolean lSet(String key List<Object> value long time) { try { redisTemplate.opsForList().rightPushAll(key value); if (time > 0) expire(key time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据索引修改list中的某条数据 * * @param key 键 * @param index 索引 * @param value 值 * @return */ public boolean lUpdateIndex(String key long index Object value) { try { redisTemplate.opsForList().set(key index value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 移除N个值为value * * @param key 键 * @param count 移除多少个 * @param value 值 * @return 移除的个数 */ public long lRemove(String key long count Object value) { try { Long remove = redisTemplate.opsForList().remove(key count value); return remove; } catch (Exception e) { e.printStackTrace(); return 0; } } }4.4 Mysql 数据库操作

数据库的 sql 文件 UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.aphysia.springdemo.mapper.UserMapper"> <select id="getAllUsers" resultType="com.aphysia.springdemo.model.User"> SELECT * FROM user </select> <update id="updateUserAge" parameterType="java.lang.Integer"> update user set age=age 1 where id =#{id} </update> </mapper>

对应的 mapper 接口 UserMapper.java

package com.aphysia.springdemo.mapper; import com.aphysia.springdemo.model.User; import java.util.List; public interface UserMapper { List<User> getAllUsers(); int updateUserAge(Integer id); }4.5 Service层

先定义一个操作 User 的接口类 UserService ,包含两个方法,查询所有的 user 以及更新 user 的年龄:

package com.aphysia.springdemo.service; import com.aphysia.springdemo.model.User; import java.util.List; public interface UserService { public List<User> getAllUsers(); public void updateUserAge(); }

接口实现类 UserServiceImpl , 为了证实Redis可用,我们查询所有的用户的时候,加入了Redis缓存,优先从Redis中加载数据 :

package com.aphysia.springdemo.service.impl; import com.aphysia.springdemo.constant.RedisConstant; import com.aphysia.springdemo.mapper.UserMapper; import com.aphysia.springdemo.model.User; import com.aphysia.springdemo.service.UserService; import com.aphysia.springdemo.util.RedisUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.util.List; @Service("userService") public class UserServiceImpl implements UserService { @Resource UserMapper userMapper; @Autowired RedisUtil redisUtil; @Override public List<User> getAllUsers() { List<User> users = (List<User>) redisUtil.get(RedisConstant.ALL_USER_KEY); if(CollectionUtils.isEmpty(users)){ users = userMapper.getAllUsers(); redisUtil.set(RedisConstant.ALL_USER_KEY users); } return users; } @Override @Transactional public void updateUserAge() { redisUtil.del(RedisConstant.ALL_USER_KEY); userMapper.updateUserAge(1); userMapper.updateUserAge(2); } }4.6 Controller 控制层

增加一个测试层 TestController :

package com.aphysia.springdemo.controller; import com.aphysia.springdemo.model.User; import com.aphysia.springdemo.service.UserService; import com.aphysia.springdemo.util.RedisUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; @Controller public class TestController { @Autowired UserService userService; @RequestMapping("/getUserList") @ResponseBody public List<User> getUserList() { return userService.getAllUsers(); } @RequestMapping("/update") @ResponseBody public int update() { userService.updateUserAge(); return 1; } }4.7 pom依赖

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.6</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.aphysia</groupId> <artifactId>springdemo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springdemo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--mysql数据库驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>测试

启动项目,输入链接: http://localhost:8081/getUserList,可以获取到所有的 user :

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(8)

我们更新一下所有的用户年龄 调用 http://localhost:8081/update 返回 1

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(9)

再次访问 http://localhost:8081/getUserList 可以看到年龄全部都变成 12 :

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(10)

怎么知道 Redis 生效了呢?最好就是 debug ,或者直接看控制台,我们已经开启了 debug 级别的日志:

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(11)

还有一种方式,下载 Redis-desktop-manager ,可以直接可视化查看:

基于docker快速搭建hdfs+hive+flume(如何基于Docker快速搭建)(12)

至此,一个 demo 项目就完成了,可以每次 copy 出来初始化使用。

原文 http://www.cnblogs.com/Damaer/p/15700586.html

猜您喜欢: