Hi Fabian, that sounds good, thank you.
One final question: As I said earlier, this also distributes data in some unnecessary cases, say ID 4 sends data to ID 3. Is there no way to find out the ID of the current node? I guess that number is already available on the node and just needs to be exposed somehow, right? Cheers Stefan On 17 September 2015 at 18:39, Fabian Hueske <fhue...@gmail.com> wrote: > Hi Stefan, > > I think I have a solution for your problem :-) > > 1) Distribute both parts of the small data to each machine (you have done > that) > 2) Your mapper should have a parallelism of 10, the tasks with ID 0 to 4 > (get ID via RichFunction.getRuntimeContext().getIndexOfThisSubtask()) read > the first half, tasks 5 to 9 read the second half. > 3) Give the large input into a FlatMapper which sends out two records for > each incoming record and assigns the first outgoing record a task ID in > range 0 to 4 and the second outgoing record an ID in range 5 to 9. > 4) Have a custom partitioner (DataSet.partitionCustom()) after the > duplicating mapper, which partitions the records based on the assigned task > Id before they go into the mapper with the other smaller data set. A record > with assigned task ID 0 will be sent to the mapper task with subtask index > 0. > > This setup is not very nice, but should work. > > Let me know, if you need more detail. > > Cheers, Fabian > > 2015-09-16 21:44 GMT+02:00 Stefan Bunk <stefan.b...@googlemail.com>: > >> Hi Fabian, >> >> the local file problem would however not exist, if I just copy both >> halves to all nodes, right? >> >> Lets say I have a file `1st` and a file `2nd`, which I copy to all nodes. >> Now with your approach from above, I do: >> >> // helper broadcast datasets to know on which half to operate >> val data1stHalf = env.fromCollection("1st") >> val data2ndHalf = env.fromCollection("2nd") >> >> val mapped1 = data.flatMap(yourMap).withBroadcastSet(data1stHalf, >> "fileName").setParallelism(5) >> val mapped2 = data.flatMap(yourMap).withBroadcastSet(data2ndHalf, >> "fileName").setParallelism(5) >> DataSet result = mapped1.union(mapped2) >> >> Then, in my custom operator implementation of flatMap I check the helper >> broadcast data to know which file to load: >> override def open(params: Configuration): Unit = { >> val fileName = >> getRuntimeContext.getBroadcastVariable[String]("fileName")(0) >> // read the file from the local filesystem which I copied there earlier >> this.data = loadFromFileIntoDatastructure("/home/data/" + fileName) >> } >> override def flatMap(document: Input, out: Collector[Output]): Unit = { >> // do sth. with this.data and the input >> out.collect(this.data.process(input)) >> } >> >> I think this should work, or do you see another problem here? >> >> Which brings us to the other question: >> The both halves are so large, that one half of the data fits in the >> user-remaining memory on a node, but not both halves. So my program would >> probably memory-crash, if the scheduling trusts one node so much, that it >> wants to execute two flatMaps there ;-). >> >> You are saying, that it is not guaranteed, that all 10 nodes are used, >> but how likely is it, that one node is given two flatMaps and another one >> is basically idling? I have no idea of the internals, but I guess there is >> some heuristic inside which decides how to distribute.In the normal setup >> that all 10 nodes are up, connection is good, all nodes have the same >> resources available, input data is evenly distributed in HDFS, then the >> default case should be to distribute to all 10 nodes, right? >> >> I am not running in production, so for me it would be ok, if this works >> out usually. >> >> Cheers >> Stefan >> >> >> On 15 September 2015 at 23:40, Fabian Hueske <fhue...@gmail.com> wrote: >> >>> Hi Stefan, >>> >>> the problem is that you cannot directly influence the scheduling of >>> tasks to nodes to ensure that you can read the data that you put in the >>> local filesystems of your nodes. HDFS gives a shared file system which >>> means that each node can read data from anywhere in the cluster. >>> I assumed the data is small enough to broadcast because you want to keep >>> it in memory. >>> >>> Regarding your question. It is not guaranteed that two different tasks, >>> each with parallelism 5, will be distributed to all 10 nodes (even if you >>> have only 10 processing slots). >>> What would work is to have one map task with parallelism 10 and a Flink >>> setup with 10 task managers on 10 machines with only one processing slot >>> per TM. However, you won't be able to replicate the data to both sets of >>> maps because you cannot know which task instance will be executed on which >>> machine (you cannot distinguish the tasks of both task sets). >>> >>> As I said, reading from local file system in a cluster and forcing task >>> scheduling to specific nodes is quite tricky. >>> Cheers, Fabian >>> >>> 2015-09-15 23:15 GMT+02:00 Stefan Bunk <stefan.b...@googlemail.com>: >>> >>>> Hi Fabian, >>>> >>>> I think we might have a misunderstanding here. I have already copied >>>> the first file to five nodes, and the second file to five other nodes, >>>> outside of Flink. In the open() method of the operator, I just read that >>>> file via normal Java means. I do not see, why this is tricky or how HDFS >>>> should help here. >>>> Then, I have a normal Flink DataSet, which I want to run through the >>>> operator (using the previously read data in the flatMap implementation). As >>>> I run the program several times, I do not want to broadcast the data every >>>> time, but rather just copy it on the nodes, and be fine with it. >>>> >>>> Can you answer my question from above? If the setParallelism-method >>>> works and selects five nodes for the first flatMap and five _other_ nodes >>>> for the second flatMap, then that would be fine for me if there is no other >>>> easy solution. >>>> >>>> Thanks for your help! >>>> Best >>>> Stefan >>>> >>>> >>>> On 14 September 2015 at 22:28, Fabian Hueske <fhue...@gmail.com> wrote: >>>> >>>>> Hi Stefan, >>>>> >>>>> forcing the scheduling of tasks to certain nodes and reading files >>>>> from the local file system in a multi-node setup is actually quite tricky >>>>> and requires a bit understanding of the internals. >>>>> It is possible and I can help you with that, but would recommend to >>>>> use a shared filesystem such as HDFS if that is possible. >>>>> >>>>> Best, Fabian >>>>> >>>>> 2015-09-14 19:16 GMT+02:00 Stefan Bunk <stefan.b...@googlemail.com>: >>>>> >>>>>> Hi, >>>>>> >>>>>> actually, I am distributing my data before the program starts, >>>>>> without using broadcast sets. >>>>>> >>>>>> However, the approach should still work, under one condition: >>>>>> >>>>>>> DataSet mapped1 = >>>>>>> data.flatMap(yourMap).withBroadcastSet(smallData1,"data").setParallelism(5); >>>>>>> DataSet mapped2 = >>>>>>> data.flatMap(yourMap).withBroadcastSet(smallData2,"data").setParallelism(5); >>>>>>> >>>>>> Is it guaranteed, that this selects a disjoint set of nodes, i.e. >>>>>> five nodes for mapped1 and five other nodes for mapped2? >>>>>> >>>>>> Is there any way of selecting the five nodes concretely? Currently, I >>>>>> have stored the first half of the data on nodes 1-5 and the second half >>>>>> on >>>>>> nodes 6-10. With this approach, I guess, nodes are selected randomly so I >>>>>> would have to copy both halves to all of the nodes. >>>>>> >>>>>> Best, >>>>>> Stefan >>>>>> >>>>>> >>>>> >>>> >>> >> >