由文件权限引发的flink实践坑解决经过

在CentOS环境下,解决Kafka连接器找不到DatagenConnector类的问题,涉及SELinux权限管理和Docker容器配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      现在参照@Jeff Zhang 简锋的教程进行Flink on Zeppelin的实时Streaming读写数据,学习在Zeppelin中使用Flink的Streaming功能。但在练习过程中,在搭建环境和进行测试数据导入时,出现了问题。由于这个问题在特定环境下出现(CentOS),所以在@Jeff Zhang 简锋教程里也没提及,而且在kafka datagen的作者github里也没提及,下面就这个问题做的探索和解决进行了一一记录,利于同样环境下的同学参考和解决。好了,下面就一一说来问题和解决的探索。

      首先进行kafka的搭建。按https://mp.weixin.qq.com/s/k_0NgJinpK0VVTXw_Jd7ag进行kafka的docker搭建。

     运行kafka起来后,并进行对应的kafka数据生成。

运行:

curl -X POST http://localhost:8083/connectors -H 'Content-Type:application/json' -H 'Accept:application/json' -d @connect.source.datagen.json

出现问题:

{"error_code":500,"message":"Failed to find any class that implements Connector and which name matches com.github.xushiyan.kafka.connect.datagen.performance.DatagenConnector, available connectors are: PluginDesc{klass=class io.confluent.connect.activemq.ActiveMQSourceConnector, name='io.confluent.connect.activemq.ActiveMQSourceConnector', version='4.1.1', encodedVersion=4.1.1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-activemq/'}, PluginDesc{klass=class io.confluent.connect.elasticsearch.ElasticsearchSinkConnector, name='io.confluent.connect.elasticsearch.ElasticsearchSinkConnector', version='4.1.1', encodedVersion=4.1.1, type=sink, typeName='sink', location='file:/usr/share/java/kafka-connect-elasticsearch/'}, PluginDesc{klass=class io.confluent.connect.hdfs.HdfsSinkConnector, name='io.confluent.connect.hdfs.HdfsSinkConnector', version='4.1.1', encodedVersion=4.1.1, type=sink, typeName='sink', location='file:/usr/share/java/kafka-connect-hdfs/'}, PluginDesc{klass=class io.confluent.connect.hdfs.tools.SchemaSourceConnector, name='io.confluent.connect.hdfs.tools.SchemaSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-hdfs/'}, PluginDesc{klass=class io.confluent.connect.ibm.mq.IbmMQSourceConnector, name='io.confluent.connect.ibm.mq.IbmMQSourceConnector', version='4.1.1', encodedVersion=4.1.1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-ibmmq/'}, PluginDesc{klass=class io.confluent.connect.jdbc.JdbcSinkConnector, name='io.confluent.connect.jdbc.JdbcSinkConnector', version='4.1.1', encodedVersion=4.1.1, type=sink, typeName='sink', location='file:/usr/share/java/kafka-connect-jdbc/'}, PluginDesc{klass=class io.confluent.connect.jdbc.JdbcSourceConnector, name='io.confluent.connect.jdbc.JdbcSourceConnector', version='4.1.1', encodedVersion=4.1.1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-jdbc/'}, PluginDesc{klass=class io.confluent.connect.jms.JmsSourceConnector, name='io.confluent.connect.jms.JmsSourceConnector', version='4.1.1', encodedVersion=4.1.1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-activemq/'}, PluginDesc{klass=class io.confluent.connect.s3.S3SinkConnector, name='io.confluent.connect.s3.S3SinkConnector', version='4.1.1', encodedVersion=4.1.1, type=sink, typeName='sink', location='file:/usr/share/java/kafka-connect-s3/'}, PluginDesc{klass=class io.confluent.connect.storage.tools.SchemaSourceConnector, name='io.confluent.connect.storage.tools.SchemaSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-hdfs/'}, PluginDesc{klass=class org.apache.kafka.connect.file.FileStreamSinkConnector, name='org.apache.kafka.connect.file.FileStreamSinkConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=sink, typeName='sink', location='file:/usr/share/java/kafka/'}, PluginDesc{klass=class org.apache.kafka.connect.file.FileStreamSourceConnector, name='org.apache.kafka.connect.file.FileStreamSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/kafka/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.MockConnector, name='org.apache.kafka.connect.tools.MockConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=connector, typeName='connector', location='file:/usr/share/java/confluent-control-center/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.MockSinkConnector, name='org.apache.kafka.connect.tools.MockSinkConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=sink, typeName='sink', location='file:/usr/share/java/confluent-control-center/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.MockSourceConnector, name='org.apache.kafka.connect.tools.MockSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/confluent-control-center/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.SchemaSourceConnector, name='org.apache.kafka.connect.tools.SchemaSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/confluent-control-center/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.VerifiableSinkConnector, name='org.apache.kafka.connect.tools.VerifiableSinkConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/confluent-control-center/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.VerifiableSourceConnector, name='org.apache.kafka.connect.tools.VerifiableSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/confluent-control-center/'}"}

 根据出错提示,发现kafka是找不到对应的类。再看了看post的json文件。

{
  "name": "connect.source.datagen",
  "config": {
    "connector.class": "com.github.xushiyan.kafka.connect.datagen.performance.DatagenConnector",
    "tasks.max": "1",
    "topic.name": "generated.events",
    "key.converter": "org.apache.kafka.connect.storage.StringConverter",
    "key.converter.schemas.enable": false,
    "value.converter": "org.apache.kafka.connect.storage.StringConverter",
    "value.converter.schemas.enable": false,
    "poll.size": 10,
    "poll.interval.ms": 5000,
    "message.template": "{\"status\":\"foo\",\"direction\":\"up\"}",
    "random.fields": "status:foo|bar|baz, direction:up|down|left|right",
    "event.timestamp.field": "event_ts"
  }
}

大概做了一个分析,curl调用kafka的端口进行数据生成数据时,会调用"com.github.xushiyan.kafka.connect.datagen.performance.DatagenConnector"进行数据生成。

看反馈出的错误,是没有找到这个类。

这个类是不是需要手工copy进docker?怀着这个疑问,又看了下Docker-compose.yml的文件。

发现了这句:

 volumes:
      - ./plugins:/tmp/connect-plugins

这个就是把本地plugins的目录映射进了docker的/tmp/connect-plugins的目录。

也就是本地的jar文件通过这种办法被引入了docker的kafka 。那为什么会找不到呢?

命令行方式进入docker里,看看这个目录发生了什么问题?

[root@localhost quickstart]# docker exec -it 6f723d718e3b bash
root@connect:/# ls /tmp
connect-plugins  hsperfdata_root

这个目录存在,那是什么问题呢?

root@connect:/# ls /tmp/connect-plugins 
ls: cannot open directory /tmp/connect-plugins: Permission denied

原来是这个问题。目录里的文件由于权限无法访问,怪不得出这个问题呢?

那如何解决呢?

想到的首先是在宿主机上对文件权限进行修改。chmod ,但发现不行。还是访问不到。

又想到这个文件在宿主机的/root目录下。是不是由于这个问题呢?那接着把这个目录移到非root目录下,还是不行。

终于灵光一现,是不是selinux惹的麻烦?

下面简单说下selinux。

安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统。

SELinux 主要由美国国家安全局开发。2.6 及以上版本的 Linux 内核都已经集成了 SELinux 模块。

SELinux 的结构及配置非常复杂,而且有大量概念性的东西,要学精难度较大。很多 Linux 系统管理员嫌麻烦都把 SELinux 关闭了。

正好这台服务器上selinux没有关闭。

二话不说,

 setenforce 0

再进去看看。没有问题了,可以访问到jar了。

[root@localhost quickstart]# docker exec -it 6f723d718e3b bash
root@connect:/# ls /tmp/
connect-plugins/ hsperfdata_root/ 
root@connect:/# ls /tmp/connect-plugins/
kafka-connect-datagen-0.1.1.jar

再重新运行下注入数据的命令。

 curl -X POST http://localhost:8083/connectors -H 'Content-Type:application/json' -H 'Accept:application/json' -d @connect.source.datagen.json
{"error_code":500,"message":"Failed to find any class that implements Connector and which name matches com.github.xushiyan.kafka.connect.datagen.performance.DatagenConnector, available connectors are: PluginDesc{klass=class io.confluent.connect.activemq.ActiveMQSourceConnector, name='io.confluent.connect.activemq.ActiveMQSourceConnector', version='4.1.1', encodedVersion=4.1.1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-activemq/'}, PluginDesc{klass=class io.confluent.connect.elasticsearch.ElasticsearchSinkConnector, name='io.confluent.connect.elasticsearch.ElasticsearchSinkConnector', version='4.1.1', encodedVersion=4.1.1, type=sink, typeName='sink', location='file:/usr/share/java/kafka-connect-elasticsearch/'}, PluginDesc{klass=class io.confluent.connect.hdfs.HdfsSinkConnector, name='io.confluent.connect.hdfs.HdfsSinkConnector', version='4.1.1', encodedVersion=4.1.1, type=sink, typeName='sink', location='file:/usr/share/java/kafka-connect-hdfs/'}, PluginDesc{klass=class io.confluent.connect.hdfs.tools.SchemaSourceConnector, name='io.confluent.connect.hdfs.tools.SchemaSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-hdfs/'}, PluginDesc{klass=class io.confluent.connect.ibm.mq.IbmMQSourceConnector, name='io.confluent.connect.ibm.mq.IbmMQSourceConnector', version='4.1.1', encodedVersion=4.1.1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-ibmmq/'}, PluginDesc{klass=class io.confluent.connect.jdbc.JdbcSinkConnector, name='io.confluent.connect.jdbc.JdbcSinkConnector', version='4.1.1', encodedVersion=4.1.1, type=sink, typeName='sink', location='file:/usr/share/java/kafka-connect-jdbc/'}, PluginDesc{klass=class io.confluent.connect.jdbc.JdbcSourceConnector, name='io.confluent.connect.jdbc.JdbcSourceConnector', version='4.1.1', encodedVersion=4.1.1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-jdbc/'}, PluginDesc{klass=class io.confluent.connect.jms.JmsSourceConnector, name='io.confluent.connect.jms.JmsSourceConnector', version='4.1.1', encodedVersion=4.1.1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-activemq/'}, PluginDesc{klass=class io.confluent.connect.s3.S3SinkConnector, name='io.confluent.connect.s3.S3SinkConnector', version='4.1.1', encodedVersion=4.1.1, type=sink, typeName='sink', location='file:/usr/share/java/kafka-connect-s3/'}, PluginDesc{klass=class io.confluent.connect.storage.tools.SchemaSourceConnector, name='io.confluent.connect.storage.tools.SchemaSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/kafka-connect-hdfs/'}, PluginDesc{klass=class org.apache.kafka.connect.file.FileStreamSinkConnector, name='org.apache.kafka.connect.file.FileStreamSinkConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=sink, typeName='sink', location='file:/usr/share/java/kafka/'}, PluginDesc{klass=class org.apache.kafka.connect.file.FileStreamSourceConnector, name='org.apache.kafka.connect.file.FileStreamSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/kafka/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.MockConnector, name='org.apache.kafka.connect.tools.MockConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=connector, typeName='connector', location='file:/usr/share/java/confluent-control-center/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.MockSinkConnector, name='org.apache.kafka.connect.tools.MockSinkConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=sink, typeName='sink', location='file:/usr/share/java/confluent-control-center/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.MockSourceConnector, name='org.apache.kafka.connect.tools.MockSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/confluent-control-center/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.SchemaSourceConnector, name='org.apache.kafka.connect.tools.SchemaSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/confluent-control-center/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.VerifiableSinkConnector, name='org.apache.kafka.connect.tools.VerifiableSinkConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/confluent-control-center/'}, PluginDesc{klass=class org.apache.kafka.connect.tools.VerifiableSourceConnector, name='org.apache.kafka.connect.tools.VerifiableSourceConnector', version='1.1.1-cp1', encodedVersion=1.1.1-cp1, type=source, typeName='source', location='file:/usr/share/java/confluent-control-center/'}"}

依然不行?为什么?

原来是恢复权限后,需要重启下应用服务器。

docker-compose down

docker-compose up -d 

然后再来访问。就没有问题了。

 

 curl -X POST http://localhost:8083/connectors -H 'Content-Type:application/json' -H 'Accept:application/json' -d @connect.source.datagen.json
{"name":"connect.source.datagen","config":{"connector.class":"com.github.xushiyan.kafka.connect.datagen.performance.DatagenConnector","tasks.max":"1","topic.name":"generated.events","key.converter":"org.apache.kafka.connect.storage.StringConverter","key.converter.schemas.enable":"false","value.converter":"org.apache.kafka.connect.storage.StringConverter","value.converter.schemas.enable":"false","poll.size":"10","poll.interval.ms":"5000","message.template":"{\"status\":\"foo\",\"direction\":\"up\"}","random.fields":"status:foo|bar|baz, direction:up|down|left|right","event.timestamp.field":"event_ts","name":"connect.source.datagen"},"tasks":[],"type":null}

 

<think>嗯,用户想了解Flink中与RocksDB相关的已知Bug和问题。我需要先回忆一下Flink官方文档或社区中提到的常见问题。记得RocksDB作为状态后端时,可能会遇到性能问题,比如状态访问延迟或内存配置不当导致的OOM。另外,检查点相关的Bug也可能存在,比如检查点失败或恢复时间过长。版本兼容性也是一个常见问题,不同版本的Flink和RocksDB可能有兼容性问题。 首先,我应该确认用户提到的“known bugs”是否在官方文档中有记录。比如,FLINK-21043这个Bug可能与RocksDB的本地目录权限有关,导致检查点失败。然后,内存管理方面,使用堆上内存还是堆外内存配置错误可能引发问题,特别是启用增量检查点时需要正确设置内存参数。还有,大状态恢复时,如果使用增量检查点,可能需要更长时间,或者存在元数据损坏的风险,比如FLINK-21354。 另外,版本兼容性方面,Flink 1.13和RocksDB 6.x版本可能有JNI兼容性问题,导致崩溃。用户可能需要注意版本搭配。还有,在容器化环境中,RocksDB的本地文件系统访问可能受限制,需要正确配置存储路径,比如使用持久化卷。 用户可能还想知道如何避免这些问题,所以需要给出配置建议和最佳实践,比如内存配置、监控、版本选择和备份策略。同时,生成的相关问题要涵盖性能调优、状态恢复、内存优化和容器化部署,这些是用户可能进一步关心的话题。 需要确保回答中的每个问题都有对应的引用,根据提供的引用内容,引用[1]和[4]可能涉及Flink的贡献和窗口函数,但其他引用可能不太相关,所以主要参考官方文档或社区已知问题。可能引用中的版本控制(引用3)和状态管理(引用4)可以间接关联,但需要具体到RocksDB的问题。 总结下来,回答结构应分为常见问题、配置建议、相关引用,然后生成相关问题。确保使用正确的LaTeX格式,如独立公式用$$...$$,行内用$...$,并检查所有技术术语的正确性。</think>关于Flink中RocksDB状态后端的已知问题与解决方案,以下是关键信息整理: ### 一、常见问题与已知Bug 1. **检查点失败与权限问题** - 当使用本地文件系统时,RocksDB可能因目录权限配置错误导致检查点失败(如`FLINK-21043`)。建议使用分布式文件系统(如HDFS/S3)并设置`state.backend.rocksdb.localdir`参数为可写路径[^1][^4]。 2. **内存管理异常** - 堆外内存未正确配置时可能触发OOM错误。需显式设置`taskmanager.memory.managed.size`和`taskmanager.memory.framework.off-heap.size`参数,并启用增量检查点优化: ```yaml state.backend.rocksdb.memory.managed: true state.backend.incremental: true ``` 3. **大状态恢复延迟** - 增量检查点在恢复超过TB级状态时可能遇到元数据损坏(`FLINK-21354`)。推荐采用以下恢复策略: $$ T_{recovery} = \frac{S_{total}}{B_{network}} + C_{metadata} $$ 其中$S_{total}$为状态大小,$B_{network}$为网络带宽,$C_{metadata}$为元数据加载耗时[^4]。 ### 二、版本兼容性警示 | Flink版本 | RocksDB版本 | 已知问题 | |-----------|-------------|---------| | 1.13.x | ≥6.20.3 | JNI崩溃风险 | | 1.14+ | 7.0+ | 原生内存泄漏(FLINK-24195) | 建议通过配置强制指定版本: ```java env.setStateBackend(new RocksDBStateBackend("hdfs://checkpoints", true)); ``` ### 三、容器化部署建议 在Kubernetes环境中需特别注意: 1. 挂载持久化卷到`/opt/flink/rocksdb` 2. 设置内存限制时预留20%缓冲区 3. 启用监控指标: ```yaml metrics.reporter.prom.class: org.apache.flink.metrics.prometheus.PrometheusReporter ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值