Hi, Hao, In this case, it will return an empty set or list in the end.
Sincerely, Hanyu On Wed, Oct 4, 2023 at 10:29 PM Matthias J. Sax <mj...@apache.org> wrote: > Great discussion! > > It seems the only open question might be about ordering guarantees? > IIRC, we had a discussion about this in the past. > > > Technically (at least from my POV), existing `RangeQuery` does not have > a guarantee that data is return in any specific order (not even on a per > partitions bases). It just happens that RocksDB (and as pointed out by > Hanyu already, also the built-in in-memory store that is base on a > tree-map) allows us to return data ordered by key; as mentioned already, > this guarantee is limited on a per partition basis. > > If there would be custom store base on a hashed key-value store, this > store could implement RangeQuery and return data (even for a single > partition) with no ordering, without violating the contract. > > > > Thus, it could actually make sense, to extend `RangeQuery` and allow > three options: no-order, ascending, descending. For our existing > Rocks/InMemory implementations, no-order could be equal to ascending and > nothing changes effectively, but it might be a better API contract? -- > If we assume that there might be a custom hash-based store, such a store > could reject a query if "ascending" is required, or might need to do > more work to implement it (up to the store maintainer). This is actually > the beauty of IQv2 that different stores can pick what queries they want > to support. > > From an API contract point of view, it seems confusing to say: > specifying nothing means no guarantee (or ascending if the store can > offer it), but descending can we explicitly request. Thus, a hash-based > store, might be able to accept "order not specified query", but would > reject "descending". This seems to be somewhat unbalanced? > > Thus, I am wondering if we should actually add `withAscendingKeys()`, > too, even if it won't impact our current RocksDB/In-Memory implementations? > > > The second question is about per-partition or across-partition ordering: > it's not possible right now to actually offer across-partition ordering > the way IQv2 is setup. The reason is, that the store that implements a > query type, is always a single shard. Thus, the implementation does not > have access to other shards. It's hard-coded inside Kafka Streams, to > query each shared, and to "accumulate" partial results, and return the > back to the user. Note that the API is: > > > > StateQueryResult<R> result = KafkaStreams.query(...); > > Map<Integer, QueryResult<R>> resultPerPartitions = > result.getPartitionResults(); > > > Thus, if we would want to offer across-partition ordering, we cannot do > it right now, because Kafka Streams does not know anything about the > semantics of the query it distributes... -- the result is an unknown > type <R>. We would need to extend IQv2 with an additional mechanism, > that allows users to plug in more custom code to "merge" multiple > partitions result into a "global result". This is clearly out-of-scope > for this KIP and would require a new KIP by itself. > > I seems that this contract, which is independent of the query type is > not well understood, and thus a big +1 to fix the documentation. I don't > think that this KIP must "define" anything, but it might of course be > worth to add the explanation why the KIP cannot even offer > global-ordering, as it's defined/limited by the IQv2 "framework" itself, > not the individual queries. > > > > -Matthias > > > > > On 10/4/23 4:38 PM, Hao Li wrote: > > Hi Hanyu, > > > > Thanks for the KIP! Seems there are already a lot of good discussions. I > > only have two comments: > > > > 1. Please make it clear in > > ``` > > /** > > * Interactive range query using a lower and upper bound to filter > the > > keys returned. > > * @param lower The key that specifies the lower bound of the range > > * @param upper The key that specifies the upper bound of the range > > * @param <K> The key type > > * @param <V> The value type > > */ > > public static <K, V> RangeQuery<K, V> withRange(final K lower, > final K > > upper) { > > return new RangeQuery<>(Optional.ofNullable(lower), > > Optional.ofNullable(upper), true); > > } > > ``` > > that a `null` in lower or upper parameter means it's unbounded. > > 2. What's the behavior if lower is 3 and upper is 1? Is it > IllegalArgument > > or will this return an empty result? Maybe also clarify this in the > > document. > > > > Thanks, > > Hao > > > > > > On Wed, Oct 4, 2023 at 9:27 AM Hanyu (Peter) Zheng > > <pzh...@confluent.io.invalid> wrote: > > > >> For testing purposes, we previously used a Set to record the results in > >> IQv2StoreIntegrationTest. Let's take an example where we now have two > >> partitions and four key-value pairs: <0,0> in p0, <1,1> in p1, <2,2> in > p0, > >> and <3,3> in p1. > >> > >> If we execute withRange(1,3), it will return a Set of <1, 2, 3>. > However, > >> if we run withRange(1,3).withDescendingKeys(), and still use a Set, the > >> result will again be a Set of <1,2,3>. This means we won't be able to > >> determine whether the results have been reversed. > >> > >> To resolve this ambiguity, I've switched to using a List to record the > >> results, ensuring the order of retrieval from partitions p0 and p1. So, > >> withRange(1,3) would yield a List of [2, 1, 3], whereas > >> withRange(1,3).withDescendingKeys() would produce a List of [2,3,1]. > >> > >> This ordering makes sense since RocksDB sorts its keys, and > InMemoryStore > >> uses a TreeMap structure, which means the keys are already sorted. > >> > >> Sincerely, > >> Hanyu > >> > >> On Wed, Oct 4, 2023 at 9:25 AM Hanyu (Peter) Zheng <pzh...@confluent.io > > > >> wrote: > >> > >>> Hi, Bruno > >>> > >>> Thank you for your suggestions, I will update them soon. > >>> Sincerely, > >>> > >>> Hanyu > >>> > >>> On Wed, Oct 4, 2023 at 9:25 AM Hanyu (Peter) Zheng < > pzh...@confluent.io> > >>> wrote: > >>> > >>>> Hi, Lucas, > >>>> > >>>> Thank you for your suggestions. > >>>> I will update the KIP and code together. > >>>> > >>>> Sincerely, > >>>> Hanyu > >>>> > >>>> On Tue, Oct 3, 2023 at 8:16 PM Hanyu (Peter) Zheng < > pzh...@confluent.io > >>> > >>>> wrote: > >>>> > >>>>> If we use WithDescendingKeys() to generate a RangeQuery to do the > >>>>> reveseQuery, how do we achieve the methods like withRange, > >> withUpperBound, > >>>>> and withLowerBound only in this method? > >>>>> > >>>>> On Tue, Oct 3, 2023 at 8:01 PM Hanyu (Peter) Zheng < > >> pzh...@confluent.io> > >>>>> wrote: > >>>>> > >>>>>> I believe there's no need to introduce a method like > >>>>>> WithDescendingKeys(). Instead, we can simply add a reverse flag to > >>>>>> RangeQuery. Each method within RangeQuery would then accept an > >> additional > >>>>>> parameter. If the reverse is set to true, it would indicate the > >> results > >>>>>> should be reversed. > >>>>>> > >>>>>> Initially, I introduced a reverse variable. When set to false, the > >>>>>> RangeQuery class behaves normally. However, when reverse is set to > >> true, > >>>>>> the RangeQuery essentially takes on the functionality of > >> ReverseRangeQuery. > >>>>>> Further details can be found in the "Rejected Alternatives" section. > >>>>>> > >>>>>> In my perspective, RangeQuery is a class responsible for creating a > >>>>>> series of RangeQuery objects. It offers methods such as withRange, > >>>>>> withUpperBound, and withLowerBound, allowing us to generate objects > >>>>>> representing different queries. I'm unsure how adding a > >>>>>> withDescendingOrder() method would be compatible with the other > >> methods, > >>>>>> especially considering that, based on KIP 969, WithDescendingKeys() > >> doesn't > >>>>>> appear to take any input variables. And if withDescendingOrder() > >> doesn't > >>>>>> accept any input, how does it return a RangeQuery? > >>>>>> > >>>>>> On Tue, Oct 3, 2023 at 4:37 PM Hanyu (Peter) Zheng < > >> pzh...@confluent.io> > >>>>>> wrote: > >>>>>> > >>>>>>> Hi, Colt, > >>>>>>> The underlying structure of inMemoryKeyValueStore is treeMap. > >>>>>>> Sincerely, > >>>>>>> Hanyu > >>>>>>> > >>>>>>> On Tue, Oct 3, 2023 at 4:34 PM Hanyu (Peter) Zheng < > >>>>>>> pzh...@confluent.io> wrote: > >>>>>>> > >>>>>>>> Hi Bill, > >>>>>>>> 1. I will update the KIP in accordance with the PR and synchronize > >>>>>>>> their future updates. > >>>>>>>> 2. I will use that name. > >>>>>>>> 3. you mean add something about ordering at the motivation > section? > >>>>>>>> > >>>>>>>> Sincerely, > >>>>>>>> Hanyu > >>>>>>>> > >>>>>>>> > >>>>>>>> On Tue, Oct 3, 2023 at 4:29 PM Hanyu (Peter) Zheng < > >>>>>>>> pzh...@confluent.io> wrote: > >>>>>>>> > >>>>>>>>> Hi, Walker, > >>>>>>>>> > >>>>>>>>> 1. I will update the KIP in accordance with the PR and > synchronize > >>>>>>>>> their future updates. > >>>>>>>>> 2. I will use that name. > >>>>>>>>> 3. I'll provide additional details in that section. > >>>>>>>>> 4. I intend to utilize rangeQuery to achieve what we're referring > >> to > >>>>>>>>> as reverseQuery. In essence, reverseQuery is merely a term. To > >> clear up any > >>>>>>>>> ambiguity, I'll make necessary adjustments to the KIP. > >>>>>>>>> > >>>>>>>>> Sincerely, > >>>>>>>>> Hanyu > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> On Tue, Oct 3, 2023 at 4:09 PM Hanyu (Peter) Zheng < > >>>>>>>>> pzh...@confluent.io> wrote: > >>>>>>>>> > >>>>>>>>>> Ok, I will change it back to following the code, and update them > >>>>>>>>>> together. > >>>>>>>>>> > >>>>>>>>>> On Tue, Oct 3, 2023 at 2:27 PM Walker Carlson > >>>>>>>>>> <wcarl...@confluent.io.invalid> wrote: > >>>>>>>>>> > >>>>>>>>>>> Hello Hanyu, > >>>>>>>>>>> > >>>>>>>>>>> Looking over your kip things mostly make sense but I have a > >> couple > >>>>>>>>>>> of > >>>>>>>>>>> comments. > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> 1. You have "withDescandingOrder()". I think you mean > >>>>>>>>>>> "descending" :) > >>>>>>>>>>> Also there are still a few places in the do where its > called > >>>>>>>>>>> "setReverse" > >>>>>>>>>>> 2. Also I like "WithDescendingKeys()" better > >>>>>>>>>>> 3. I'm not sure of what ordering guarantees we are > offering. > >>>>>>>>>>> Perhaps we > >>>>>>>>>>> can add a section to the motivation clearly spelling out > the > >>>>>>>>>>> current > >>>>>>>>>>> ordering and the new offering? > >>>>>>>>>>> 4. When you say "use unbounded reverseQuery to achieve > >>>>>>>>>>> reverseAll" do > >>>>>>>>>>> you mean "use unbounded RangeQuery to achieve reverseAll"? > as > >>>>>>>>>>> far as I can > >>>>>>>>>>> tell we don't have a reverseQuery as a named object? > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> Looking good so far > >>>>>>>>>>> > >>>>>>>>>>> best, > >>>>>>>>>>> Walker > >>>>>>>>>>> > >>>>>>>>>>> On Tue, Oct 3, 2023 at 2:13 PM Colt McNealy < > c...@littlehorse.io > >>> > >>>>>>>>>>> wrote: > >>>>>>>>>>> > >>>>>>>>>>>> Hello Hanyu, > >>>>>>>>>>>> > >>>>>>>>>>>> Thank you for the KIP. I agree with Matthias' proposal to keep > >>>>>>>>>>> the naming > >>>>>>>>>>>> convention consistent with KIP-969. I favor the > >>>>>>>>>>> `.withDescendingKeys()` > >>>>>>>>>>>> name. > >>>>>>>>>>>> > >>>>>>>>>>>> I am curious about one thing. RocksDB guarantees that records > >>>>>>>>>>> returned > >>>>>>>>>>>> during a range scan are lexicographically ordered by the bytes > >>>>>>>>>>> of the keys > >>>>>>>>>>>> (either ascending or descending order, as specified in the > >>>>>>>>>>> query). This > >>>>>>>>>>>> means that results within a single partition are indeed > >>>>>>>>>>> ordered.** My > >>>>>>>>>>>> reading of KIP-805 suggests to me that you don't need to > >> specify > >>>>>>>>>>> the > >>>>>>>>>>>> partition number you are querying in IQv2, which means that > you > >>>>>>>>>>> can have a > >>>>>>>>>>>> valid reversed RangeQuery over a store with "multiple > >>>>>>>>>>> partitions" in it. > >>>>>>>>>>>> > >>>>>>>>>>>> Currently, IQv1 does not guarantee order of keys in this > >>>>>>>>>>> scenario. Does > >>>>>>>>>>>> IQv2 support ordering across partitions? Such an > implementation > >>>>>>>>>>> would > >>>>>>>>>>>> require opening a rocksdb range scan** on multiple rocksdb > >>>>>>>>>>> instances (one > >>>>>>>>>>>> per partition), and polling the first key of each. Whether or > >>>>>>>>>>> not this is > >>>>>>>>>>>> ordered, could we please add that to the documentation? > >>>>>>>>>>>> > >>>>>>>>>>>> **(How is this implemented/guaranteed in an > >>>>>>>>>>> `inMemoryKeyValueStore`? I > >>>>>>>>>>>> don't know about that implementation). > >>>>>>>>>>>> > >>>>>>>>>>>> Colt McNealy > >>>>>>>>>>>> > >>>>>>>>>>>> *Founder, LittleHorse.dev* > >>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>>> On Tue, Oct 3, 2023 at 1:35 PM Hanyu (Peter) Zheng > >>>>>>>>>>>> <pzh...@confluent.io.invalid> wrote: > >>>>>>>>>>>> > >>>>>>>>>>>>> ok, I will update it. Thank you Matthias > >>>>>>>>>>>>> > >>>>>>>>>>>>> Sincerely, > >>>>>>>>>>>>> Hanyu > >>>>>>>>>>>>> > >>>>>>>>>>>>> On Tue, Oct 3, 2023 at 11:23 AM Matthias J. Sax < > >>>>>>>>>>> mj...@apache.org> > >>>>>>>>>>>> wrote: > >>>>>>>>>>>>> > >>>>>>>>>>>>>> Thanks for the KIP Hanyu! > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> I took a quick look and it think the proposal makes sense > >>>>>>>>>>> overall. > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> A few comments about how to structure the KIP. > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> As you propose to not add `ReverseRangQuery` class, the > >> code > >>>>>>>>>>> example > >>>>>>>>>>>>>> should go into "Rejected Alternatives" section, not in the > >>>>>>>>>>> "Proposed > >>>>>>>>>>>>>> Changes" section. > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> For the `RangeQuery` code example, please omit all existing > >>>>>>>>>>> methods > >>>>>>>>>>>> etc, > >>>>>>>>>>>>>> and only include what will be added/changed. This make it > >>>>>>>>>>> simpler to > >>>>>>>>>>>>>> read the KIP. > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> nit: typo > >>>>>>>>>>>>>> > >>>>>>>>>>>>>>> the fault value is false > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> Should be "the default value is false". > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> Not sure if `setReverse()` is the best name. Maybe > >>>>>>>>>>>> `withDescandingOrder` > >>>>>>>>>>>>>> (or similar, I guess `withReverseOrder` would also work) > >>>>>>>>>>> might be > >>>>>>>>>>>>>> better? Would be good to align to KIP-969 proposal that > >>>>>>>>>>> suggest do use > >>>>>>>>>>>>>> `withDescendingKeys` methods for "reverse key-range"; if we > >>>>>>>>>>> go with > >>>>>>>>>>>>>> `withReverseOrder` we should change KIP-969 accordingly. > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> Curious to hear what others think about naming this > >>>>>>>>>>> consistently across > >>>>>>>>>>>>>> both KIPs. > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> -Matthias > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>>> On 10/3/23 9:17 AM, Hanyu (Peter) Zheng wrote: > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>> > >> > https://cwiki.apache.org/confluence/display/KAFKA/KIP-985%3A+Add+reverseRange+and+reverseAll+query+over+kv-store+in+IQv2 > >>>>>>>>>>>>>>> > >>>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> -- > >>>>>>>>>>>>> > >>>>>>>>>>>>> [image: Confluent] <https://www.confluent.io> > >>>>>>>>>>>>> Hanyu (Peter) Zheng he/him/his > >>>>>>>>>>>>> Software Engineer Intern > >>>>>>>>>>>>> +1 (213) 431-7193 <+1+(213)+431-7193> > >>>>>>>>>>>>> Follow us: [image: Blog] > >>>>>>>>>>>>> < > >>>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>> > >> > https://www.confluent.io/blog?utm_source=footer&utm_medium=email&utm_campaign=ch.email-signature_type.community_content.blog > >>>>>>>>>>>>>> [image: > >>>>>>>>>>>>> Twitter] <https://twitter.com/ConfluentInc>[image: LinkedIn] > >>>>>>>>>>>>> <https://www.linkedin.com/in/hanyu-peter-zheng/>[image: > >> Slack] > >>>>>>>>>>>>> <https://slackpass.io/confluentcommunity>[image: YouTube] > >>>>>>>>>>>>> <https://youtube.com/confluent> > >>>>>>>>>>>>> > >>>>>>>>>>>>> [image: Try Confluent Cloud for Free] > >>>>>>>>>>>>> < > >>>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>> > >> > https://www.confluent.io/get-started?utm_campaign=tm.fm-apac_cd.inbound&utm_source=gmail&utm_medium=organic > >>>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> > >>>>>>>>>> -- > >>>>>>>>>> > >>>>>>>>>> [image: Confluent] <https://www.confluent.io> > >>>>>>>>>> Hanyu (Peter) Zheng he/him/his > >>>>>>>>>> Software Engineer Intern > >>>>>>>>>> +1 (213) 431-7193 <+1+(213)+431-7193> > >>>>>>>>>> Follow us: [image: Blog] > >>>>>>>>>> < > >> > https://www.confluent.io/blog?utm_source=footer&utm_medium=email&utm_campaign=ch.email-signature_type.community_content.blog > >>> [image: > >>>>>>>>>> Twitter] <https://twitter.com/ConfluentInc>[image: LinkedIn] > >>>>>>>>>> <https://www.linkedin.com/in/hanyu-peter-zheng/>[image: Slack] > >>>>>>>>>> <https://slackpass.io/confluentcommunity>[image: YouTube] > >>>>>>>>>> <https://youtube.com/confluent> > >>>>>>>>>> > >>>>>>>>>> [image: Try Confluent Cloud for Free] > >>>>>>>>>> < > >> > https://www.confluent.io/get-started?utm_campaign=tm.fm-apac_cd.inbound&utm_source=gmail&utm_medium=organic > >>> > >>>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> -- > >>>>>>>>> > >>>>>>>>> [image: Confluent] <https://www.confluent.io> > >>>>>>>>> Hanyu (Peter) Zheng he/him/his > >>>>>>>>> Software Engineer Intern > >>>>>>>>> +1 (213) 431-7193 <+1+(213)+431-7193> > >>>>>>>>> Follow us: [image: Blog] > >>>>>>>>> < > >> > https://www.confluent.io/blog?utm_source=footer&utm_medium=email&utm_campaign=ch.email-signature_type.community_content.blog > >>> [image: > >>>>>>>>> Twitter] <https://twitter.com/ConfluentInc>[image: LinkedIn] > >>>>>>>>> <https://www.linkedin.com/in/hanyu-peter-zheng/>[image: Slack] > >>>>>>>>> <https://slackpass.io/confluentcommunity>[image: YouTube] > >>>>>>>>> <https://youtube.com/confluent> > >>>>>>>>> > >>>>>>>>> [image: Try Confluent Cloud for Free] > >>>>>>>>> < > >> > https://www.confluent.io/get-started?utm_campaign=tm.fm-apac_cd.inbound&utm_source=gmail&utm_medium=organic > >>> > >>>>>>>>> > >>>>>>>> > >>>>>>>> > >>>>>>>> -- > >>>>>>>> > >>>>>>>> [image: Confluent] <https://www.confluent.io> > >>>>>>>> Hanyu (Peter) Zheng he/him/his > >>>>>>>> Software Engineer Intern > >>>>>>>> +1 (213) 431-7193 <+1+(213)+431-7193> > >>>>>>>> Follow us: [image: Blog] > >>>>>>>> < > >> > https://www.confluent.io/blog?utm_source=footer&utm_medium=email&utm_campaign=ch.email-signature_type.community_content.blog > >>> [image: > >>>>>>>> Twitter] <https://twitter.com/ConfluentInc>[image: LinkedIn] > >>>>>>>> <https://www.linkedin.com/in/hanyu-peter-zheng/>[image: Slack] > >>>>>>>> <https://slackpass.io/confluentcommunity>[image: YouTube] > >>>>>>>> <https://youtube.com/confluent> > >>>>>>>> > >>>>>>>> [image: Try Confluent Cloud for Free] > >>>>>>>> < > >> > https://www.confluent.io/get-started?utm_campaign=tm.fm-apac_cd.inbound&utm_source=gmail&utm_medium=organic > >>> > >>>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> -- > >>>>>>> > >>>>>>> [image: Confluent] <https://www.confluent.io> > >>>>>>> Hanyu (Peter) Zheng he/him/his > >>>>>>> Software Engineer Intern > >>>>>>> +1 (213) 431-7193 <+1+(213)+431-7193> > >>>>>>> Follow us: [image: Blog] > >>>>>>> < > >> > https://www.confluent.io/blog?utm_source=footer&utm_medium=email&utm_campaign=ch.email-signature_type.community_content.blog > >>> [image: > >>>>>>> Twitter] <https://twitter.com/ConfluentInc>[image: LinkedIn] > >>>>>>> <https://www.linkedin.com/in/hanyu-peter-zheng/>[image: Slack] > >>>>>>> <https://slackpass.io/confluentcommunity>[image: YouTube] > >>>>>>> <https://youtube.com/confluent> > >>>>>>> > >>>>>>> [image: Try Confluent Cloud for Free] > >>>>>>> < > >> > https://www.confluent.io/get-started?utm_campaign=tm.fm-apac_cd.inbound&utm_source=gmail&utm_medium=organic > >>> > >>>>>>> > >>>>>> > >>>>>> > >>>>>> -- > >>>>>> > >>>>>> [image: Confluent] <https://www.confluent.io> > >>>>>> Hanyu (Peter) Zheng he/him/his > >>>>>> Software Engineer Intern > >>>>>> +1 (213) 431-7193 <+1+(213)+431-7193> > >>>>>> Follow us: [image: Blog] > >>>>>> < > >> > https://www.confluent.io/blog?utm_source=footer&utm_medium=email&utm_campaign=ch.email-signature_type.community_content.blog > >>> [image: > >>>>>> Twitter] <https://twitter.com/ConfluentInc>[image: LinkedIn] > >>>>>> <https://www.linkedin.com/in/hanyu-peter-zheng/>[image: Slack] > >>>>>> <https://slackpass.io/confluentcommunity>[image: YouTube] > >>>>>> <https://youtube.com/confluent> > >>>>>> > >>>>>> [image: Try Confluent Cloud for Free] > >>>>>> < > >> > https://www.confluent.io/get-started?utm_campaign=tm.fm-apac_cd.inbound&utm_source=gmail&utm_medium=organic > >>> > >>>>>> > >>>>> > >>>>> > >>>>> -- > >>>>> > >>>>> [image: Confluent] <https://www.confluent.io> > >>>>> Hanyu (Peter) Zheng he/him/his > >>>>> Software Engineer Intern > >>>>> +1 (213) 431-7193 <+1+(213)+431-7193> > >>>>> Follow us: [image: Blog] > >>>>> < > >> > https://www.confluent.io/blog?utm_source=footer&utm_medium=email&utm_campaign=ch.email-signature_type.community_content.blog > >>> [image: > >>>>> Twitter] <https://twitter.com/ConfluentInc>[image: LinkedIn] > >>>>> <https://www.linkedin.com/in/hanyu-peter-zheng/>[image: Slack] > >>>>> <https://slackpass.io/confluentcommunity>[image: YouTube] > >>>>> <https://youtube.com/confluent> > >>>>> > >>>>> [image: Try Confluent Cloud for Free] > >>>>> < > >> > https://www.confluent.io/get-started?utm_campaign=tm.fm-apac_cd.inbound&utm_source=gmail&utm_medium=organic > >>> > >>>>> > >>>> > >>>> > >>>> -- > >>>> > >>>> [image: Confluent] <https://www.confluent.io> > >>>> Hanyu (Peter) Zheng he/him/his > >>>> Software Engineer Intern > >>>> +1 (213) 431-7193 <+1+(213)+431-7193> > >>>> Follow us: [image: Blog] > >>>> < > >> > https://www.confluent.io/blog?utm_source=footer&utm_medium=email&utm_campaign=ch.email-signature_type.community_content.blog > >>> [image: > >>>> Twitter] <https://twitter.com/ConfluentInc>[image: LinkedIn] > >>>> <https://www.linkedin.com/in/hanyu-peter-zheng/>[image: Slack] > >>>> <https://slackpass.io/confluentcommunity>[image: YouTube] > >>>> <https://youtube.com/confluent> > >>>> > >>>> [image: Try Confluent Cloud for Free] > >>>> < > >> > https://www.confluent.io/get-started?utm_campaign=tm.fm-apac_cd.inbound&utm_source=gmail&utm_medium=organic > >>> > >>>> > >>> > >>> > >>> -- > >>> > >>> [image: Confluent] <https://www.confluent.io> > >>> Hanyu (Peter) Zheng he/him/his > >>> Software Engineer Intern > >>> +1 (213) 431-7193 <+1+(213)+431-7193> > >>> Follow us: [image: Blog] > >>> < > >> > https://www.confluent.io/blog?utm_source=footer&utm_medium=email&utm_campaign=ch.email-signature_type.community_content.blog > >>> [image: > >>> Twitter] <https://twitter.com/ConfluentInc>[image: LinkedIn] > >>> <https://www.linkedin.com/in/hanyu-peter-zheng/>[image: Slack] > >>> <https://slackpass.io/confluentcommunity>[image: YouTube] > >>> <https://youtube.com/confluent> > >>> > >>> [image: Try Confluent Cloud for Free] > >>> < > >> > https://www.confluent.io/get-started?utm_campaign=tm.fm-apac_cd.inbound&utm_source=gmail&utm_medium=organic > >>> > >>> > >> > >> > >> -- > >> > >> [image: Confluent] <https://www.confluent.io> > >> Hanyu (Peter) Zheng he/him/his > >> Software Engineer Intern > >> +1 (213) 431-7193 <+1+(213)+431-7193> > >> Follow us: [image: Blog] > >> < > >> > https://www.confluent.io/blog?utm_source=footer&utm_medium=email&utm_campaign=ch.email-signature_type.community_content.blog > >>> [image: > >> Twitter] <https://twitter.com/ConfluentInc>[image: LinkedIn] > >> <https://www.linkedin.com/in/hanyu-peter-zheng/>[image: Slack] > >> <https://slackpass.io/confluentcommunity>[image: YouTube] > >> <https://youtube.com/confluent> > >> > >> [image: Try Confluent Cloud for Free] > >> < > >> > https://www.confluent.io/get-started?utm_campaign=tm.fm-apac_cd.inbound&utm_source=gmail&utm_medium=organic > >>> > >> > > > -- [image: Confluent] <https://www.confluent.io> Hanyu (Peter) Zheng he/him/his Software Engineer Intern +1 (213) 431-7193 <+1+(213)+431-7193> Follow us: [image: Blog] <https://www.confluent.io/blog?utm_source=footer&utm_medium=email&utm_campaign=ch.email-signature_type.community_content.blog>[image: Twitter] <https://twitter.com/ConfluentInc>[image: LinkedIn] <https://www.linkedin.com/in/hanyu-peter-zheng/>[image: Slack] <https://slackpass.io/confluentcommunity>[image: YouTube] <https://youtube.com/confluent> [image: Try Confluent Cloud for Free] <https://www.confluent.io/get-started?utm_campaign=tm.fm-apac_cd.inbound&utm_source=gmail&utm_medium=organic>