Hi Xuannan, I have one question more from a strategic point of view: given that we're working on Flink 2.0, wouldn't we actually want to be in a situation where object-reuse is always used and don't make it configurable anymore? IIRC, the only reason why it's a configuration is for backward compatibility.
Best regards, Martijn On Tue, Sep 26, 2023 at 1:32 AM Xuannan Su <suxuanna...@gmail.com> wrote: > > Hi all, > > We would like to revive the discussion and provide a quick update on > the recent work of the FLIP. We have implemented a POC[1], run cases > in the flink-benchmarks[2] against the POC, and verified that many of > the operators in the benchmark will enable object-reuse without code > changes, while the global object-reuse is disabled. > > Please let me know if you have any further comments on the FLIP. If > there are no more comments, we will open the voting in 3 days. > > Best regards, > Xuannan > > [1] https://github.com/apache/flink/pull/22897 > [2] https://github.com/apache/flink-benchmarks > > > On Fri, Jul 7, 2023 at 9:18 AM Dong Lin <lindon...@gmail.com> wrote: > > > > Hi Jing, > > > > Thank you for the suggestion. Yes, we can extend it to support null if in > > the future we find any use-case for this flexibility. > > > > Best, > > Dong > > > > On Thu, Jul 6, 2023 at 7:55 PM Jing Ge <j...@ververica.com> wrote: > > > > > Hi Dong, > > > > > > one scenario I could imagine is that users could enable global object > > > reuse features but force deep copy for some user defined specific > > > functions > > > because of any limitations. But that is only my gut feeling. And agree, we > > > could keep the solution simple for now as FLIP described and upgrade to > > > 3VL > > > once there are such real requirements that are rising. > > > > > > Best regards, > > > Jing > > > > > > On Thu, Jul 6, 2023 at 12:30 PM Dong Lin <lindon...@gmail.com> wrote: > > > > > >> Hi Jing, > > >> > > >> Thank you for the detailed explanation. Please see my reply inline. > > >> > > >> On Thu, Jul 6, 2023 at 3:17 AM Jing Ge <j...@ververica.com> wrote: > > >> > > >>> Hi Xuannan, Hi Dong, > > >>> > > >>> Thanks for your clarification. > > >>> > > >>> @Xuannan > > >>> > > >>> A Jira ticket has been created for the doc update: > > >>> https://issues.apache.org/jira/browse/FLINK-32546 > > >>> > > >>> @Dong > > >>> > > >>> I don't have a concrete example. I just thought about it from a > > >>> conceptual or pattern's perspective. Since we have 1. coarse-grained > > >>> global > > >>> switch(CGS as abbreviation), i.e. the pipeline.object-reuse and 2. > > >>> fine-grained local switch(FGS as abbreviation), i.e. the > > >>> objectReuseCompliant variable for specific operators/functions, there > > >>> will > > >>> be the following patterns with appropriate combinations: > > >>> > > >>> pattern 1: coarse-grained switch only. Local object reuse will be > > >>> controlled by the coarse-grained switch: > > >>> 1.1 cgs == true -> local object reused enabled > > >>> 1.2 cgs == true -> local object reused enabled > > >>> 1.3 cgs == false -> local object reused disabled, i.e. deep copy enabled > > >>> 1.4 cgs == false -> local object reused disabled, i.e. deep copy enabled > > >>> > > >>> afaiu, this is the starting point. I wrote 4 on purpose to make the > > >>> regression check easier. We can consider it as the combinations with > > >>> cgs(true/false) and fgs(true/false) while fgs is ignored. > > >>> > > >>> Now we introduce fine-grained switch. There will be two patterns: > > >>> > > >>> pattern 2: fine-grained switch over coarse-grained switch. > > >>> Coarse-grained switch will be ignored when the local fine-grained switch > > >>> has different value: > > >>> 2.1 cgs == true and fgs == true -> local object reused enabled > > >>> 2.2 cgs == true and fgs == false -> local object reused disabled, i.e. > > >>> deep copy enabled > > >>> 2.3 cgs == false and fgs == true -> local object reused enabled > > >>> 2.4 cgs == false and fgs == false -> local object reused disabled, i.e. > > >>> deep copy enabled > > >>> > > >>> cgs is actually ignored. > > >>> > > >>> Current FLIP is using a slightly different pattern: > > >>> > > >>> pattern 3: fine-grained switch over coarse-grained switch only when > > >>> coarse-grained switch is off, i..e cgs OR fgs: > > >>> 3.1 cgs == true and fgs == true -> local object reused enabled > > >>> 3.2 cgs == true and fgs == false -> local object reused enabled > > >>> 3.3 cgs == false and fgs == true -> local object reused enabled > > >>> 3.4 cgs == false and fgs == false -> local object reused disabled, i.e. > > >>> deep copy enabled > > >>> > > >>> All of those patterns are rational and each has different focus. It > > >>> depends on the real requirement to choose one of them. > > >>> > > >>> As we can see, if fgs is using 2VL, there is a regression between > > >>> pattern 1 and pattern 2. You are absolutely right in this case. That's > > >>> why > > >>> I suggested 3VL, i.e. fgs will have triple values: true, false, > > >>> unknown(e.g. null) > > >>> > > >>> pattern 4: 3VL fgs with the null as init value (again, there are just > > >>> two combination, I made it 4 on purpose): > > >>> 4.1 cgs == true and fgs == null -> local object reused enabled > > >>> 4.2 cgs == true and fgs == null -> local object reused enabled > > >>> 4.3 cgs == false and fgs == null -> local object reused disabled, i.e. > > >>> deep copy enabled > > >>> 4.4 cgs == false and fgs == null -> local object reused disabled, i.e. > > >>> deep copy enabled > > >>> > > >>> Since the default value of fgs is null, pattern 4 is backward compatible > > >>> with pattern 1, which means no regression. > > >>> > > >>> Now we will set value to fgs and follow the pattern 2: > > >>> 4.5 cgs == true and fgs == true -> local object reused enabled > > >>> 4.6 cgs == true and fgs == false -> local object reused disabled, i.e. > > >>> deep copy enabled > > >>> 4.7 cgs == false and fgs == true -> local object reused enabled > > >>> 4.8 cgs == false and fgs == false -> local object reused disabled, i.e. > > >>> deep copy enabled > > >>> > > >>> Pattern 4 contains pattern 3 with the following combinations(force > > >>> enabling local object reuse): > > >>> 4.5 cgs == true and fgs == true -> local object reused enabled > > >>> 4.2 cgs == true and fgs == null -> local object reused enabled > > >>> 4.7 cgs == false and fgs == true -> local object reused enabled > > >>> 4.4 cgs == false and fgs == null -> local object reused disabled, i.e. > > >>> deep copy enabled > > >>> > > >>> Comparing pattern 4 to pattern 3, user will have one additional > > >>> flexibility to control(force disabling) the local object reuse > > >>> capability > > >>> because of 3VL, i.e. 4.2+4.6 vs. 3.2. > > >>> > > >> > > >> I think you are suggesting to allow the user setting fgs to null so that > > >> "user will have one additional flexibility to control(force disabling) > > >> the > > >> local object reuse capability". > > >> > > >> In general, an API that only allows false/true is a bit more complex to > > >> implement than an API that allows false/true/null. All things being > > >> equal, > > >> I believe it is preferred to have a simpler public API. > > >> > > >> I understand you are coming from a conceptual perspective and trying to > > >> make it similar to hierarchical RBAC. However, after thinking through > > >> this, > > >> I still could not find a use-case where we actually need this > > >> flexibility. > > >> In particular, for cases where a user has explicitly configured > > >> pipeline.object-reuse to true, that means the user already knows (or > > >> takes > > >> the responsibility of ensuring) that correctness can be achieved, why > > >> would > > >> the user want to explicitly disable the object-reuse for an operator? > > >> > > >> Regards, > > >> Dong > > >> > > >> > > >>> > > >>> It is commonly used in the hierarchical RBAC to enable more fine-grained > > >>> access control of sub role. > > >>> > > >>> I hope I have been able to explain myself clearly. Looking forward to > > >>> your feedback. > > >>> > > >>> Best regards, > > >>> Jing > > >>> > > >>> > > >>> > > >>> On Wed, Jul 5, 2023 at 12:47 PM Dong Lin <lindon...@gmail.com> wrote: > > >>> > > >>>> Hi Jing, > > >>>> > > >>>> Thanks for the comments! Please find below my comments, which are based > > >>>> on the offline discussion with Xuannan. > > >>>> > > >>>> On Wed, Jul 5, 2023 at 1:36 AM Jing Ge <j...@ververica.com> wrote: > > >>>> > > >>>>> Hi Xuannan, Hi Dong > > >>>>> > > >>>>> Thanks for the Proposal! After reading the FLIP, I'd like to ask some > > >>>>> questions: > > >>>>> > > >>>>> 1. Naming convention for boolean variables. It is recommended to > > >>>>> follow JavaBean [1], i.e. objectReuseCompliant as the variable name > > >>>>> with > > >>>>> isObjectReuseCompliant() and setObjectReuseCompliant() as the > > >>>>> methods' name. > > >>>>> > > >>>>> > > >>>> Good point. We have updated the FLIP as suggested. > > >>>> > > >>>> > > >>>>> > > >>>>> 2. > > >>>>> > > >>>>> - > > >>>>> > > >>>>> *If pipeline.object-reuse is set to true, records emitted by this > > >>>>> operator will be re-used.* > > >>>>> - > > >>>>> > > >>>>> *Otherwise, if getIsObjectReuseCompliant() returns true, records > > >>>>> emitted by this operator will be re-used.* > > >>>>> - > > >>>>> > > >>>>> *Otherwise, records emitted by this operator will be deep-copied > > >>>>> before being given to the next operator in the chain.* > > >>>>> > > >>>>> > > >>>>> If I understand you correctly, the hard coding objectReusedCompliant > > >>>>> should have higher priority over the configuration, the checking logic > > >>>>> should be: > > >>>>> > > >>>>> - > > >>>>> > > >>>>> *If getIsObjectReuseCompliant() returns true, records emitted by > > >>>>> this operator will be re-used.* > > >>>>> - > > >>>>> > > >>>>> *Otherwise, if pipeline.object-reuse is set to true, records > > >>>>> emitted by this operator will be re-used.* > > >>>>> - > > >>>>> > > >>>>> *Otherwise, records emitted by this operator will be deep-copied > > >>>>> before being given to the next operator in the chain.* > > >>>>> > > >>>>> > > >>>>> The results are the same but the checking logics are different, but > > >>>>> there are some additional thoughts, which lead us to the next > > >>>>> question. > > >>>>> > > >>>> > > >>>>> > > >>>> > > >>>>> 3. Current design lets specific operators enable object reuse and > > >>>>> ignore the global config. There could be another thought, on the > > >>>>> contrary: > > >>>>> if an operator has hard coded the objectReuseCompliant as false, i.e. > > >>>>> disable object reuse on purpose, records should not be reused even if > > >>>>> the > > >>>>> global config pipeline.object-reused is set to true, which turns out > > >>>>> that > > >>>>> the objectReuseCompliant could be a triple value logic: ture: force > > >>>>> object > > >>>>> reusing; false: force deep-copying; unknown: depends on > > >>>>> pipeline.object-reuse config. > > >>>>> > > >>>> > > >>>> With the current proposal, if pipeline.object-reused == true and > > >>>> operatorA's objectReuseCompliant == false, Flink will not deep-copy > > >>>> operatorA's output. I think you are suggesting changing the behavior > > >>>> such > > >>>> that Flink should deep-copy the operatorA's output. > > >>>> > > >>>> Could you explain what is the advantage of this approach compared to > > >>>> the approach described in the FLIP? > > >>>> > > >>>> My concern with this approach is that it can cause performance > > >>>> regression. This is an operator's objectReuseCompliant will be false by > > >>>> default unless it is explicitly overridden. For those jobs which are > > >>>> currently configured with pipeline.object-reused = true, these jobs > > >>>> will > > >>>> likely start to have lower performance (due to object deep-copy) after > > >>>> upgrading to the newer Flink version. > > >>>> > > >>>> Best, > > >>>> Dong > > >>>> > > >>>> > > >>>>> > > >>>>> Best regards, > > >>>>> Jing > > >>>>> > > >>>>> > > >>>>> [1] https://en.wikipedia.org/wiki/JavaBeans > > >>>>> > > >>>>> On Mon, Jul 3, 2023 at 4:25 AM Xuannan Su <suxuanna...@gmail.com> > > >>>>> wrote: > > >>>>> > > >>>>>> Hi all, > > >>>>>> > > >>>>>> Dong(cc'ed) and I are opening this thread to discuss our proposal to > > >>>>>> add operator attribute to allow operator to specify support for > > >>>>>> object-reuse [1]. > > >>>>>> > > >>>>>> Currently, the default configuration for pipeline.object-reuse is set > > >>>>>> to false to avoid data corruption, which can result in suboptimal > > >>>>>> performance. We propose adding APIs that operators can utilize to > > >>>>>> inform the Flink runtime whether it is safe to reuse the emitted > > >>>>>> records. This enhancement would enable Flink to maximize its > > >>>>>> performance using the default configuration. > > >>>>>> > > >>>>>> Please refer to the FLIP document for more details about the proposed > > >>>>>> design and implementation. We welcome any feedback and opinions on > > >>>>>> this proposal. > > >>>>>> > > >>>>>> Best regards, > > >>>>>> > > >>>>>> Dong and Xuannan > > >>>>>> > > >>>>>> [1] > > >>>>>> https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=255073749 > > >>>>>> > > >>>>>